⚙️

【create-react-app】webpackのaliasをTypeScriptでも有効にする方法は

2021/08/15に公開

はじめに

create-react-app(以下、cra)めちゃくちゃ便利ですよね。
また、TypeScriptでもサクッとテンプレートを作成できるのがグッドです。

で、craでwebpackの設定いじりたいなーって時に私は「craco」というライブラリを使います。
https://www.npmjs.com/package/@craco/craco

今回はこのcracoを使って、上記のaliasの設定をしていきます。(厳密にはwebpackに定義するわけではないのですが...)

普通にaliasを設定する

まず、cracoをVanillaなJSテンプレートで使う場合の、webpackのalias設定は下記のような感じです。

const path = require("path");

module.exports = {
    mode: process.env.REACT_APP_ENVIROMENT,
    output: {
        path: __dirname
    },
    // webpack setting
    webpack: {
        alias: {
            "@": path.resolve(__dirname, "src"),
        },
    }
};

webpackキー内のオブジェクトにまんまwebpackの書き方でaliasの設定をすることによって、react-scriptsのwebpack.config.jsをオーバーライドすることができます。

TypeScriptの場合

ただ、TypeScriptのテンプレートだとtsconfig.jsonの方にもパスエイリアスを指定しなくてはなりません。(厳密にはtsconfig.jsonだけでいい)

まず、普通にtsconfig.jsonにパスエイリアスの設定として、下記のように追記したのですがこれだとなぜかpathsだけが削除されてしまいます。

{
...
"compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@/*" : ["./*"]
    }
  }
...
 }

これは、craがpathsのオプションに対応していないため、と記載されていました。
https://stackoverflow.com/questions/59132027/will-remove-paths-in-tsconfig-automatically-when-i-start-the-app

で、解決策としてはcracoを使ってcraの拡張を行う、というものです。

TypeScriptでもaliasを設定する

方法自体は、下記のissueの回答を参考にしました。
https://stackoverflow.com/questions/57070052/create-react-app-typescript-3-5-path-alias

まず、必要なファイルは

  1. craco.config.js
  2. tsconfig.json
  3. tsconfig.paths.json

の三つです。
それぞれのファイルを見ていきましょう。

  • craco.config.js
const CracoAlias = require("craco-alias");

module.exports = {
    mode: process.env.REACT_APP_ENVIROMENT,
    output: {
        path: __dirname
    },
    // webpack setting
    webpack: {
        configure: {
        }
    },
    // craco plugin setting
    plugins: [
        {
            plugin: CracoAlias,
            options: {
                source: "tsconfig",
                baseUrl: "./src",
                tsConfigPath: "./tsconfig.paths.json"
            }
        }
    ]
};

「craco-alias」というcraco自体のプラグインを使います。
https://www.npmjs.com/package/craco-alias

  • tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "es6",
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true
  },
  "include": [
    "src"
  ],
  "extends": "./tsconfig.paths.json"
}

重要なのはextendsの部分に作成したtsconfig.jsonを指定することですね。

  • tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@/*" : ["./*"]
    }
  }
}

この拡張用のファイルでパスエイリアスを指定しています。
これで、普通のwebpackのaliasと同じように動作するはずです。

まとめ

つらつら書いていきましたが、tsconfig.jsonのbaseUrlだけで、絶対的にパスを読み込んでくれるのでどうしても明示的にエイリアスを指定したい時じゃないと使うタイミングはあまりないかもですね...

cracoの使い方もまた記事にできればと思います。

Discussion