先日 create-react-app 4.0.0 がリリースされました
このバージョンでは
- react-refresh が標準搭載
- react 17 のサポート
- typescript 4 のサポート
など他にもたくさんの update がされています.
この記事の内容
issue にもあるように create-react-app でセットアップされたプロジェクトはパスエイリアスの設定をサポートしていないので 3系で作成したプロジェクトでは tsconfig.json とは別に tsconfig.paths.json などの別のファイルを用意し extends を使うことで問題を 回避 していました.
新しいバージョンで作成したプロジェクトではこの回避方法で起動しようとするとエラーが発生し起動できなくなっています.
この記事では別の回避方法で起動する手順を紹介したいと思います.
エラーの原因
-
react-scripts start 内で verifyTypeScriptSetup を呼び出す.ここでは tsconfig を読み込んで期待する中身かどうかをチェック.そうでなければ設定値補正する
-
paths
が設定された tsconfig は期待していないので ここで 中身を補正しようとする際にエラーが発生する - (readonly なプロパティに値を代入しようとしている動きなので bug っぽい...?)
-
方針
-
- verifyTypeScriptSetup が呼ばれるタイミングでは react-scripts が期待している tsconfig の中身のまま実行させる
-
- webpack の設定を構成する際に ForkTsCheckerWebpackPlugin が参照する tsconfig の中身をパスエイリアス設定済みのファイルを参照するように差し替える
- そうしないと型チェック時のモジュール解決ができません
1. react-app-rewired のインストールと設定
$ yarn add -D react-app-rewired
また package.json の起動コマンドを適宜修正します
2. tsconfig.json の修正
create-react-app で生成された tsconfig.json を別の名前にリネームします.ここでは tsconfig-react-scripts.json としましたが別の名前でもOKです.
この tsconfig は react-scripts が期待している中身にしておきたいので何も手を加えないようにします.
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
.... 生成された tsconfig.json の中身のままにする
}
それとは別で tsconfig.json も用意します.これは tsconfig-react-scripts.json を extends しつつパスエイリアスを設定します.
{
"extends": "./tsconfig-react-scripts.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"]
}
}
}
3. config-overrides.js の修正
const path = require('path');
module.exports = {
webpack: function (config, env) {
const forkTsCheckerWebpackPlugin = config.plugins.find(
(plugin) => plugin.constructor.name == 'ForkTsCheckerWebpackPlugin'
);
if (forkTsCheckerWebpackPlugin) {
// 方針2: ForkTsCheckerWebpackPlugin が参照する tsconfig の中身をパスエイリアス設定済みのファイルを参照するように差し替える
forkTsCheckerWebpackPlugin.tsconfig = path.resolve('./tsconfig.json');
}
config.resolve.alias['~'] = path.resolve('./src');
return config;
},
paths: (paths, env) => {
const overridePaths = {
...paths,
// 方針1: verifyTypeScriptSetup が参照する tsconfig のパスを差し替える
appTsConfig: path.resolve('./tsconfig-react-scripts.json'),
};
return overridePaths;
},
};
これで dev server が起動できるようになります.
jest を使う時にはもう一工夫必要なので今回の記事の内容を含めたサンプルのリポジトリを作成しました.参考にしていただければと思います.
https://github.com/Yama-Tomo/cra-v4-with-alias-import