【実務・中級編】ESLintの自動修正でバグを生む罠:–fixで壊れやすいコードパターンと安全な運用術 – デバッグ・コード品質・テストツール生産性向上バイブル

ESLint `–fix`の「静かなる破壊」を制する:自動化の罠と、真にスケールする開発環境の構築術

プロダクトが成長し、チーム規模が拡大するにつれ、「コードの標準化」は生存戦略そのものになります。しかし、ESLintの `–fix` を盲信し、CIのパイプラインに脳死で組み込んでいるなら、それは時限爆弾を抱えているのと同じです。

今日は、ツールに振り回されるのではなく、ツールを「コードの純度を高める精錬所」として使いこなすための、テックリード視点の実践知を授けます。

—

1. なぜ `–fix` は「バグの温床」になるのか

ESLintの自動修正は、AST(抽象構文木)を書き換える強力な変換プロセスです。しかし、「文法的に正しいが、セマンティクス(意味論)が破壊される」ケースが往々にして存在します。

危険なルールの筆頭例

  • `prefer-destructuring`: 配列やオブジェクトのアクセスを分割代入に強制変換しますが、`undefined` の混入や、意図しないプロパティの列挙を招くことがあります。特に、動的に決定されるプロパティアクセスにおいて、ロジックを破壊するケースが多々あります。
  • `no-useless-rename`: `import { a as a } from ‘module’` を `import { a } from ‘module’` に変えますが、特定のビルドツールやバベルのプラグインがこの変換を正しく認識できない環境では、バンドル後のコードで参照エラーを引き起こすことがあります。
  • `prefer-arrow-callback`: `function` から `=>` への変換は、`this` のスコープを根本から変えます。クラスメソッドやDOMイベントハンドラ内でこれを行うと、ランタイムエラーが即座に発生します。

教訓: `–fix` は「形式の統一」には極めて有用ですが、「リファクタリングの代用」としては不完全です。

—

2. 実務で「壊さない」ための運用アーキテクチャ

自動修正を安全に運用するには、「CIでの強制」と「ローカルでの開発体験」の分離が不可欠です。

ベストプラクティス:設定の階層化

以下の構成を推奨します。`eslint-config-prettier` を使い、Prettierとの競合を完全に排除するのが大前提です。

// .eslintrc.json の構成例
{
“extends”: [
“eslint:recommended”,
“plugin:@typescript-eslint/recommended”,
“prettier” // Prettierとの競合ルールを無効化する必須プラグイン
],
“rules”: {
// 危険なルールの自動修正はOFFにする
“prefer-destructuring”: [“error”, { “VariableDeclarator”: { “object”: false, “array”: false } }],
// チームで合意が取れていないルールは warning にし、CIをパスさせる(段階的移行)
“no-useless-rename”: “warn”
}
}

チーム開発を加速させる「神プラグイン」と設定

開発効率を劇的に上げるには、以下の3つをチーム全員のVSCodeに強制インストールさせます。

1. [ESLint Plugin](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint): 言うまでもない必須。
2. [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens): エラー内容をコード行にインライン表示し、修正コストをゼロにします。
3. [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost): インポートサイズを可視化し、バンドルサイズへの意識を醸成します。

—

3. 生産性を極限まで高めるキーボードショートカット

マウス操作は「思考のコンテキストスイッチ」を発生させます。以下のコマンドを `keybindings.json` に設定し、指に覚え込ませてください。

// keybindings.json への追記
[
{
“key”: “ctrl+shift+i”, // 任意のショートカット
“command”: “editor.action.formatDocument”, // Prettierによる整形
“when”: “editorHasDocumentFormattingProvider && editorTextFocus”
},
{
“key”: “alt+shift+f”,
“command”: “eslint.executeAutofix”, // ESLintの修正のみを実行
“when”: “editorTextFocus”
}
]

これで、「Prettierで見た目を整える」と「ESLintでロジック品質を直す」を完全に脳内で切り分けて処理できます。

—

4. 破壊を防ぐ CI/CD ゲート戦略

CI上で `–fix` を走らせてコミットさせるフローは、ローカル環境との乖離を生むため避けるべきです。代わりに、「自動修正による変更を検知してビルドを落とす」運用を推奨します。

package.json の scripts
{
“scripts”: {
“lint:check”: “eslint ‘src//.{js,ts}'”,
“lint:fix”: “eslint ‘src//.{js,ts}’ –fix”,
“ci:lint”: “eslint ‘src//.{js,ts}’ –max-warnings 0”
# –max-warnings 0 により、ワーニングすら放置させない規律を強制する
}
}

もし、どうしても自動修正をCIで行いたい場合は、「自動修正をコミットするBot」を作り、プルリクエストに対して自動的に修正コミットがプッシュされるフローを構築してください。これにより、レビュアーは「コードそのもののロジック」に集中でき、フォーマットの指摘という不毛なやり取りから解放されます。

—

結論:ツールは「ガイド」であれ、「マスター」であってはならない

ESLintやPrettierの真の価値は、「誰が書いても同じ品質・同じ形式になる」という心理的安全性の確保にあります。

  • 自動化できることは自動化する(フォーマット、末尾カンマなど)
  • 自動化してはいけないことは人間が判断する(ロジックの改善、構造的なリファクタリング)

この境界線をチーム内で定義し、設定ファイルというコードとして共有すること。それこそが、伝説的な開発チームの条件です。今日から `–fix` をただの便利ツールとしてではなく、コードベースを健全に保つための「賢明なガーディアン」として扱ってください。

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