create-react-appからTypescript+Reactで動かすまで

Posted on
javascript react
$ create-react-app my-app
$ npm run eject
$ npm install -g webpack
$ npm install --save @types/react @types/react-dom
$ npm install --save-dev typescript ts-loader source-map-loader
$ vim tsconfig.json

tsconfig.jsonを作る。内容は下記。

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ]
}

config/paths.jsのappIndexJsのパスをindex.tsxのパスに変更する。

// config after eject: we're in ./config/
module.exports = {
  dotenv: resolveApp('.env'),
  appBuild: resolveApp('build'),
  appPublic: resolveApp('public'),
  appHtml: resolveApp('public/index.html'),
-  appIndexJs: resolveApp('src/index.js'),
+  appIndexJs: resolveApp('src/index.tsx'),
  appPackageJson: resolveApp('package.json'),
  appSrc: resolveApp('src'),
  yarnLockFile: resolveApp('yarn.lock'),
  testsSetup: resolveApp('src/setupTests.js'),
  appNodeModules: resolveApp('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
};

modules.rules`に追加。

{                                                                                                                                            
  test: /\.(ts|tsx)$/,
  include: paths.appSrc,
  use: [ 
    { 
      loader: require.resolve('ts-loader'),
      options: { 
        // disable type checker - we will use it in fork plugin
        transpileOnly: true,
      },
    },
  ],
},

typescriptのドキュメント見るとawesome-typescript-loader使ってるんだけど、こいつがwebpackの4.x系に依存しているっぽくて、create-react−appにバンドルされてるwebpackが3.8.1なので

Module build failed: TypeError: Cannot read property 'watchRun' of undefined

こんな感じのエラーが出てしまう。依存関係解決しようとすると時間かかってしまいそうなので、ts−loaderでお茶を濁す。

あとは適当にindex.tsxを用意して、npm run startする。

import * as React from "react";
import * as ReactDOM from "react-dom";
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

追記

この作業している最中に見つけたのだけど、create-react-app-typescriptというパッケージが存在する。特に深く考えたくない時はこっちを利用した方が良さそう。

参考リンク