大規模リポジトリを「爆速」に。ESLint & Prettierの限界を超えるアーキテクチャ最適化
エンジニアの集中力は、Lintの実行が終わるまでの「数分間」で蒸発します。
大規模プロジェクトにおいて、ESLintが数分間走り続けるような状況は、もはや単なる待ち時間ではなく、「開発文化の腐敗」です。型チェックやユニットテストと異なり、Lintは開発プロセスの初期段階にあるはずです。ここがボトルネックになるチームは、反復速度(イテレーション)が著しく低下し、結果としてコード品質への妥協を生みます。
今日は、数万行規模のリポジトリでもLintを「一瞬」で終わらせ、開発体験を極限まで引き上げるための、深層チューニング術を伝授します。
—
1. 「キャッシュの神」を呼び出し、再計算を根絶する
ESLintのデフォルトは、実行のたびに全ファイルを走査します。これは大規模リポジトリでは自殺行為です。まずは `–cache` を「空気のように」デフォルトで導入します。
.eslintrc.json / コマンド設定
キャッシュファイル(`.eslintcache`)は `.gitignore` に含めるのが鉄則ですが、CI環境ではキャッシュを保持するためにアーティファクトとして保存・リストアする設計が必須です。
package.jsonのscriptsをこう書き換える
“lint”: “eslint ‘src//.{js,ts,tsx}’ –cache –cache-location .eslintcache –fix”
アーキテクトの知見:
なぜ `–cache-location` を明示するのか? それは、プロジェクトのルートディレクトリを汚染せず、`.gitignore` で確実に管理しやすくするためです。また、CI/CD(GitHub Actions等)では、`actions/cache` を使い、この `.eslintcache` をキーとして保存・復元することで、差分lintを爆速化できます。フルスキャンは最初の1回だけで十分です。
—
2. lint-staged を「並列実行の鬼」にする
`lint-staged` は単なる「コミット前にLintを走らせるツール」ではありません。真の価値は、「変更されたファイルのみを対象に、最適な並列処理を適用する」点にあります。
.lintstagedrc.json の極意
デフォルトの lint-staged は逐次実行しがちです。大規模プロジェクトでは、`–max-warnings 0` を付与し、かつ並列化(parallel)を意識した構成にします。
{
“.{js,ts,tsx}”: [
“eslint –cache –fix”,
“prettier –write”
],
“.{json,md}”: [
“prettier –write”
]
}
現場の最適化テクニック:
もし、`eslint` の実行に時間がかかる場合、`–parallel` オプションを検討してください。しかし、注意点があります。`eslint` 自体は単一プロセスで実行される設計が基本です。もしプロジェクトが巨大で、lintプロセスがCPUのボトルネックになるなら、`eslint` を複数プロセスに分割するのではなく、`eslint-plugin-import` などの重いプラグインを再考するか、`files` オプションで対象を厳密に絞り込む方が、結果的に「トータルコスト」は下がります。
—
3. 「無視する技術」が一番の高速化
最も速いLintは「実行されないLint」です。大規模リポジトリには、Lint不要なファイル(ビルド成果物、依存関係、自動生成コード)が必ず紛れ込んでいます。
.eslintignore の厳格化
`.gitignore` を読み込ませる設定は便利ですが、大規模リポジトリでは「重複」や「意図しない解析」を招きます。専用の `.eslintignore` を切り出し、明示的に排除します。
ビルドディレクトリ
dist/
build/
coverage/
自動生成された型定義やAPIクライアント
src/generated/
.d.ts
設定ファイル系(Lint不要)
.config.js
アーキテクトの知見:
特に `node_modules` の除外は基本ですが、`src/generated/` のような自動生成コードをLint対象から外すことを忘れるエンジニアが多い。これだけで数秒、あるいは数十秒の削減が可能です。
—
4. チーム開発を加速させる「神プラグイン」と設定共有
生産性を最大化するには、「個人の判断」を排除することです。
絶対に入れるべきプラグイン
- `eslint-plugin-import`: インポート順序の自動整理。
- `eslint-plugin-unused-imports`: 使われていないimportを自動削除。これだけでコードのモジュール化と解析負荷が劇的に下がります。
- `prettier-plugin-sort-json`: JSONファイルのソートを自動化し、Gitのコンフリクトを抑制。
究極の「設定共有」ルール
プロジェクトルートに `.eslintrc.js` を置き、`extends` を活用して設定を階層化します。
// .eslintrc.js
module.exports = {
extends: [
‘eslint:recommended’,
‘plugin:@typescript-eslint/recommended’,
‘prettier’ // Prettierとの競合を無効化する、最も重要な設定
],
rules: {
// チームの規約を強制する
‘@typescript-eslint/no-explicit-any’: ‘error’,
‘unused-imports/no-unused-imports’: ‘error’
}
};
—
5. 最後に:テックリードからのメッセージ
ツールをただ導入するだけでは、環境は改善しません。
「なぜこのルールが必要なのか?」「なぜこの設定が速いのか?」という思想をチームに共有してください。
- コマンドのエイリアス化: `npm run lint` と打つのが面倒なら `alias l=”npm run lint”` と設定させる。
- IDE連携: VSCodeの `eslint.lintTask.enable: true` を設定し、保存時に自動修正される環境を強制する。
Lint速度は「エンジニアの思考速度」に直結します。
待ち時間をゼロにする。それが、我々エンジニアが創り出すべき「最高の開発体験」です。さあ、今すぐ設定ファイルを開き、数秒の無駄を切り捨てていきましょう。