В какой-то момент борьбы со Flow-Type на VSCode, я согласился, что нужно переезжать на TypeScript. Поддержка Flow-Type обеспечивается сторонним плагином и совсем-совсем не устраивает. Если файл невалиден с точки зрения Flow-Type, то переходы внутри кода между файлами перестают работать, например. А возвращаться на WebStorm после знакомства с VSCode — я не могу себя заставить. Microsoft, как обычно, затягивает полностью. Любишь VSCode, получи TypeScript.


Если бы мне кто сказал год назад, что я вернусь в поклонники Microsoft — сложно было такое представить. Но случаются и более удивительные вещи. Я в полном восторге от качества китайского набора React-компонентов от Ant-Design. И хотя он написан на TypeScript, чтобы его прикрурить, нужен babel-plugin-import.


Но как же остаться на Create React App (CRA) — у форка для TypeScript (CRA-TS) выпилили Babel. Поддерживать собственную вариацию CRA представляется безумием. Многообещающий Preact-CLI (как замена CRA) не обеспечивает необходимый уровень совместимости с React. Но, играясь с Preact-CLI, заметил, что preact.config.js очень похож на react-app-rewired, которым я активно пользуюсь для обхода ограничений конфигурации Webpack в CRA. Сопоставил этот факт с идеей перевода CRA-TS c ts-loader на awesome-typescript-loader, внутри которого можно включить Babel. И вуаля!


0) установить create-react-app


$ npm install -g create-react-app

1) создать проект


$ create-react-app cra-ts-antd --scripts-version=react-scripts-ts
$ cd cra-ts-antd/

2) добавить пакеты


$ yarn add react-app-rewired react-app-rewire-less awesome-typescript-loader babel-core babel-plugin-import babel-preset-react-app -D

3) добавить config-overrides.js


module.exports = function override(config, env) {
  const tsLoader = config.module.rules.find(conf => {
    return conf.loader && conf.loader.includes('ts-loader')
  })
  tsLoader.loader = require.resolve('awesome-typescript-loader')
  tsLoader.query = {
    useBabel: true,
  }

  const tsLintLoader = config.module.rules.find(conf => {
    return conf.loader && conf.loader.includes('tslint-loader')
  })
  tsLintLoader.options = tsLintLoader.options || {}
  // FIXED Warning: The 'no-use-before-declare' rule requires type infomation.
  tsLintLoader.options.typeCheck = true

  const rewireLess = require('react-app-rewire-less')
  config = rewireLess(config, env)

  const path = require('path')
  // For import with absolute path
  config.resolve.modules = [path.resolve('src')].concat(config.resolve.modules)

  return config
}

4) изменить package.json; код подключает враппер react-app-rewired


  "scripts": {
-   "start": "react-scripts-ts start",
-   "build": "react-scripts-ts build",
+   "start": "BROWSER=none react-app-rewired start --scripts-version react-scripts-ts",
+   "build": "react-app-rewired build --scripts-version react-scripts-ts",
  }

5) изменить tsconfig.json; код включает настройки для абсолютного импорта, помимо прочего


{
  "compilerOptions": {
+   "allowSyntheticDefaultImports": true,
+   "baseUrl": ".",
+   "paths": {
+     "*": ["*", "src/*"]
+   },
-   "jsx": "react",
+   "jsx": "preserve",
  },
  "exclude": [
+   "config-overrides.js",
  ]
}

6) добавить .babelrc; код назначает требуемый пресет и подключает babel-plugin-import


{
  "presets": ["react-app"],
  "plugins": [
    ["import", { "libraryName": "antd", "style": false }]
  ]
}

7) добавить antd; версия фиксированная, т.к. в следующей версии 2.12.3 обнаружена ошибка


$ yarn add antd@2.12.2

8) добавить src/resources/main.less; код переопределяет переменную


@import "~antd/dist/antd.less"; // import official less entry file

@primary-color: #1DA57A;

9)… и подключить в index.tsx; импорт по абсолютному пути от src


+ import 'resources/main.less';

10) изменить App.tsx


  import * as React from 'react';
  import './App.css';
+ import { Button } from 'antd';

  const logo = require('./logo.svg');

  class App extends React.Component<{}, {}> {
    render() {
      return (
        <div className="App">
          <div className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h2>Welcome to React</h2>
          </div>
          <p className="App-intro">
            To get started, edit `src/App.tsx` and save to reload.
          </p>
+         <Button type="primary">Test</Button>
        </div>
      );
    }
  }

  export default App;

Исходники на GitHub


P.S.: Ищу работу.

Поделиться с друзьями
-->

Комментарии (8)


  1. pawlo16
    31.07.2017 21:47

    Typescript умеет в браузер через broeserify без webpack и babel если что.


  1. Listrigon
    31.07.2017 23:26

    Не знаю даже, попробовал это дело, но все равно ощущение какой-то скрытости от тебя, не понимаешь что происходит, лучше уж самому все руками поставить и иметь полный контроль, надо добавил, надо удалил. А по поводу обновлений, на выходных обновил все основные библиотеки до актуальных за пару часов и никаких проблем.


    1. comerc
      31.07.2017 23:33

      В этом весь цимес, обновление CRA хоть каждый день, без последствий за пару минут! И никакой магии, вставьте console.log(config) в config-overrides.js — конфиг webpack, как на ладони.


    1. comerc
      31.07.2017 23:38

      Затык случился лишь однажды, когда CRA переехал на Webpack 2 — тынц.


      1. Listrigon
        01.08.2017 01:19

        Так обновляются же только сами библиотеки, а нет мой код, я больше время потартил на подобные
        обновления:

        // before
        export default connect(mapStateToProps)(Something)
        
        // after
        import { withRouter } from 'react-router-dom'
        export default withRouter(connect(mapStateToProps)(Something))
        
        

        нежели на обновление версий в конкфиге.


        1. comerc
          01.08.2017 08:50

          Не понял. У вас же по коду прибавилось функционала (подключение к реакт-роутеру).


          1. Listrigon
            01.08.2017 08:57

            Код не прибавился, а изменился от одной версии роутера к другой. Это я к тому, что CRA не решает проблемы обновления кода, а только обновления самих библиотек. Поэтому личон для меня прощу все точно и четко настроить ручками явно.


            1. comerc
              01.08.2017 09:16

              Например. Сравнивая CRA и CRA-TS, меня смущает, что tsconfig.json и tslint.json торчат наружу. Да, я хотел бы иметь возможность их править при необходимости, но мне нужны "настройки по умолчанию". Это крайне ценное назначение CRA, на мой вкус.