【実務・中級編】 filesプロパティの役割 – TypeScript実践ガイド

TypeScriptの「files」プロパティを使いこなせ:巨大プロジェクトを制御下に置くための隠し味

こんにちは。現場でTypeScriptと格闘している皆さん、お疲れ様です。

`tsconfig.json` を設定する際、多くのエンジニアは `include` と `exclude` をいじって「なんとなく動いた」という状態で満足しがちです。しかし、プロジェクトが中規模を超え、複雑なビルド構成やレガシーコードとの共存が必要になった瞬間、その「なんとなく」が牙を剥くことがあります。

今日は、そんな `tsconfig.json` の中でも、少し影が薄いけれど実は非常に強力な `files` プロパティについて、現場の知見を交えて深掘りしていきましょう。

—

「files」プロパティとは何か? ― 最後の砦としての絶対指定

公式ドキュメントには「コンパイル対象とするファイルをリスト形式で指定する」と書かれていますが、これだけだと「`include` でいいじゃないか」と思いますよね。

結論から言うと、`files` は「明示的かつ絶対的な優先権を持つリスト」です。

  • `include`: globパターン(`/.ts`など)を使って、ディレクトリ単位で「ここら辺のファイルをよろしく」と指示するもの。
  • `exclude`: `include` で指定した範囲から「これだけは無視してくれ」と引き算するもの。
  • `files`: 「そんなの関係ない。このファイルはどんな状況でも絶対にコンパイルする」と宣言する、いわば指名手配リストです。

なぜ実務で「files」が必要になるのか

中級以上のエンジニアなら経験があるはずです。例えば、以下のようなケースです。

1. ごく一部の巨大な型定義ファイルを個別にインポートさせたいとき
プロジェクト全体のビルド時間を短縮するために `include` を絞り込んでいるが、特定のグローバルな型定義ファイルだけは常にコンパイルパスに乗せたい場合。
2. 依存関係の解決を強制したいとき
特定のファイルが他のどのモジュールからもインポートされていないが、実行時に動的に読み込まれる(あるいはスクリプトタグで直接読み込まれる)場合、`include` だけでは型チェックが漏れることがあります。`files` に入れることで、それを防げます。
3. 特定のレガシーファイルを「特例」として扱うとき
特定のディレクトリだけ厳格な `strict: false` で動かしたい、あるいは特定のファイルだけ個別のコンパイル戦略を取りたい場合、`files` で指定することで、他の設定との競合を避けつつ確実に検知させることができます。

—

実践的な設定例:現場で使える構成

例えば、メインのソースコードは `src/` にあるけれど、ビルド用のスクリプトや特殊な設定ファイルを個別に管理したい場合、以下のように記述します。

{
“compilerOptions”: {
“target”: “ESNext”,
“module”: “CommonJS”,
“strict”: true
},
// includeは広範囲をカバーするために使う
“include”: [“src//”],
// filesは「プロジェクトにとって聖域となるファイル」を記述する
“files”: [
“scripts/build-helper.ts”, // ビルドプロセスで使うスクリプトを個別にチェック
“types/global-overrides.d.ts” // プロジェクト全体に影響するグローバル型定義を強制指定
]
}

ここでのポイント:
`files` に記述されたファイルは、たとえ `exclude` で指定されたディレクトリ内にあってもコンパイル対象になります。これが `files` が最強たる所以です。

—

ブラウザやビルドツールはどう処理しているのか?

TypeScriptのコンパイラ(`tsc`)は、起動時に以下の順序でファイルを収集します。

1. `files` に記載されたファイルを特定する。
2. `include` に合致するファイルを探す。
3. `exclude` に該当するものを除外する。

重要なのは、`files` に書かれたファイルは「ルートファイル」として扱われるという点です。TypeScriptの言語サービスは、これらのファイルを起点にして、`import` されている依存ツリーを辿り、型チェックを行います。

もし、プロジェクトが大規模で `include` のglobパターンによるファイル走査が重すぎる場合、`include` を空にして `files` だけで構成を管理する「超硬派な構成」をとるチームもあります(ビルド速度の最適化において、これは最終手段として非常に有効です)。

—

シニアからのアドバイス:使いどころを見極める

最後に一つだけ忠告です。`files` を多用しすぎないでください。

100個も200個もファイルを `files` に書き始めると、ファイルを追加するたびに `tsconfig.json` を編集する羽目になり、メンテナンスコストが爆発します。

  • 基本戦略: `include` を適切に設計する。
  • 例外処理: どうしても漏れてしまう「特殊なエントリーポイント」や「グローバル型」だけを `files` で救い上げる。

このバランス感覚こそが、アーキテクトとしての腕の見せ所です。「何でもかんでも設定すればいい」というわけではないのが、TypeScriptの面白いところですね。

明日のコードレビューで、誰かの `tsconfig.json` が少し整理されることを楽しみにしています。それでは、また。

コメント

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