【実務・中級編】 compilerOptions.moduleの設定 – TypeScript実践ガイド

現場のコードを「動く」から「最適化する」へ:`compilerOptions.module` を完全攻略する

現場でTypeScriptを触っていて、`tsconfig.json`の`compilerOptions`をなんとなく設定したままにしていないか?

特に`module`の設定は、フロントエンド開発において「ビルド後のコードがブラウザやランタイムでどう解釈されるか」という、いわば「実行時の素性」を決める極めて重要な項目だ。ここを理解せずに「とりあえず動くから」とCommonJSのまま放置していると、Tree Shakingが効かなかったり、バンドルサイズが肥大化したりと、後々泣きを見ることになる。

今回は、中級エンジニアの君に向けて、`module`設定の深淵と実務的な最適解を叩き込む。

—

1. なぜ「module」設定が重要なのか?

TypeScriptの`module`設定は、「ソースコード内の`import`/`export`構文を、最終的にどのモジュール仕様に変換するか」を決定する。

ブラウザやNode.jsがモジュールを読み込む際の「約束事」は環境によって異なる。もし、現代のブラウザ環境なのに古いCommonJS形式(`require`/`module.exports`)で出力していたら、ブラウザは「そんなAPIは知らないよ」とエラーを吐くか、あるいはWebpackerのようなバンドラーが余計なポリフィルを挿入してコードを無駄に太らせることになる。

2. 現場で選ぶべき「最適解」の現在地

結論から言おう。現代のフロントエンド開発において、選ぶべき選択肢は基本的に以下の2つだ。

A. React, Vue, Next.js などのモダンフレームワークを使っている場合

`”module”: “ESNext”` または `”ES2022″`

現代のビルドツール(Vite, Webpack, esbuild, SWC)は、ESM(ECMAScript Modules)の形式を最も効率的に処理できる。これを指定することで、Tree Shaking(不要なコードの削除)が最大限に機能し、バンドルサイズが劇的に小さくなる。

B. Node.js環境で純粋なTSを書く場合

`”module”: “NodeNext”`

Node.jsのモジュール解決ルール(`package.json`の`type`フィールドを参照する等)は複雑だ。素人判断で`CommonJS`を指定すると、`.mjs`と`.cjs`が混在する現代のNode.js環境で痛い目を見る。`NodeNext`を指定しておけば、TypeScriptが今のNode.jsの仕様に合わせた型チェックと変換を自動で担保してくれる。

—

3. 実践:現場で使えるtsconfig.jsonの設定例

まずは、モダンなReact環境を想定した設定を見てほしい。これをそのままエディタの`tsconfig.json`に適用してみてくれ。

{
“compilerOptions”: {
/
ESNextにすることで、最新のモジュール機能を維持しつつ、
バンドラーが後から最適な形に最適化できるようにする。
/
“module”: “ESNext”,

/
モジュール解決の戦略。Bundlerにすることで、
importの拡張子省略などをビルドツールに委ねる(Viteなどで推奨)。
/
“moduleResolution”: “Bundler”,

/
これらを組み合わせるのが2024年現在の黄金セット。
ESモジュールの利点を最大限に活かせる。
/
“target”: “ES2022”,
“esModuleInterop”: true,
“skipLibCheck”: true
}
}

—

4. なぜ「CommonJS」は避けるべきなのか?

かつてのデフォルトだった`”module”: “CommonJS”`は、Node.jsの歴史的遺産だ。これをフロントエンドで使い続けると何が起きるか。

1. Tree Shakingの阻害: CommonJSは実行時までどのモジュールが必要か確定しない「動的」な仕様だ。そのため、ビルドツールが「この関数は使われていないから消そう」という最適化を物理的に行いにくい。
2. 非同期読み込みの難航: ブラウザネイティブのESM(`

シェアする
frontendintronationalをフォローする

コメント

タイトルとURLをコピーしました