🏖️

【TypeScript / Next.js】build用のtsconfig.jsonを用意してtestなどの不要なファイルを除く方法

2023/07/27に公開

やりたいこと

前提として、TypeScript/Next.jsで構成されたアプリケーションの開発の話です

TypeScriptではtsconfig.jsonでコンパイラで読み込む対象と除外する対象のファイルのパスを指定することができます

そこで、開発時には全てのファイルをコンパイル対象にし、build時にはtestやstorybookなどbuildに必要のないファイルを除外してbuildを高速化・軽量化できるようにすることができないか、というのが今回の目的です

ちなみに、ChatGPTにbuild時に不要なファイルを除外することについて聞いてみるとこんな感じの回答が返ってきました
https://chat.openai.com/share/58a50f18-e943-48f2-84fc-78f9d9408077

方針と調査

全てを含むtsconfig.jsonと、buildに不要なファイルをexcludeで除いたtsconfig.build.jsonを用意し、build時だけtsconfig.build.jsonを読み込むようにすることができれば今回の目的は達成できるのではないかと考えました

ただTypeScriptコンパイラを実行するだけであれば次のように--projectオプションで指定できます

Terminal
tsc --project tsconfig.build.json

また、webpackの場合も次の記事のようにすれば実現できます
https://mizchi.dev/202006101314-switch-tsconfig-on-webpack

しかし、Next.jsでtsconfig.jsonを切り替える方法について調べてみると意外と出てきませんでした・・・

一応、Next.jsの公式ドキュメントによるとnext.config.jsのoptionでtypescriptに関する設定ができそうに見えます
ただし、ignoreBuildErrorsの設定しか触れられていません
https://nextjs.org/docs/pages/api-reference/next-config-js/typescript

そこで、Next.jsのソースコードでtypescriptに関する設定ができないか探してみると、次の部分で指定のtsconfigPathを読み込んでくれることが分かりました
https://github.com/vercel/next.js/blob/canary/packages/next/src/build/load-jsconfig.ts#L55-L58

つまり、next.config.jstsconfigPathを指定してあげれば任意のtsconfig.jsonでbuildすることができそうです!

余談ですが、リポジトリのURLにアクセスして次のように github.comgithub.devにするとブラウザでVSCodeが開けるので検索などが楽です
https://github.dev/vercel/next.js/blob/canary/packages/next/src/build/load-jsconfig.ts#L55-L58

やってみる

まずnode_modules以外の全てをコンパイルするためのtsconfig.jsonを用意します
デフォルトでtsconfig.jsonが読み込まれるので、別途このファイルを参照するためのパスの指定はしていません

tsconfig.json
{
  "compilerOptions": {
    // 省略
  },
  "include": [
    // 省略
  ],
  "exclude": [
    "node_modules"
  ]
}

そして、tsconfig.jsonのexcludeにtestやstorybookを除外したものをtsconfig.build.jsonとします
この場合は*.test.tsx*.storybook.tsxを除外するようにしていますが、ご自身が除外したいファイルに応じて変更してください
exclude以外は同じなのでtsconfig.jsonextendsして利用します

tsconfig.build.json
{
  "extends": "./tsconfig.json",
  "exclude": [
    "node_modules",
    "**/*.test.tsx",
    "**/*.storybook.tsx"
  ]
}

あとはnext.config.jstsconfig.build.jsonを読み込むようにすれば完了です

next.config.js
module.exports = {
  typescript: {
    tsconfigPath: 'tsconfig.build.json',
  },
}

確認

next buildを実行すると次のような表示が出てtsconfig.build.jsonが参照されていることが確認できました!

Using tsconfig file: tsconfig.build.json

終わりに

公式ドキュメントにtsconfigPathに関する記述を追加するPRでも出してみようかな

Discussion