【実務・中級編】実務で差がつく!ESLintのカスタムルール作成入門:独自のコーディング規約を強制する – デバッグ・コード品質・テストツール生産性向上バイブル

規約の自動化こそが最強のアーキテクチャ:ESLintカスタムルールで「レビューコスト」をゼロにする

多くのプロジェクトで ESLint と Prettier は「コードを綺麗にするためのツール」として導入されています。しかし、それは宝の持ち腐れです。真のテックリードにとって、これらは「人間の記憶力に依存するレビューコストを排除し、チームの意思決定をコード化するエンジン」でなければなりません。

「このメソッドは直接呼ばず、必ずラッパー経由で呼んでください」
「このライブラリのこのAPIは、特定の条件下でメモリリークするから使わないでください」

こうした「口頭の注意」を繰り返していませんか?それは負債です。本稿では、AST(抽象構文木)を操作し、プロジェクト固有の禁忌をコードレベルで弾く「カスタムルール」の極意を伝授します。

—

1. なぜ「設定」ではなく「ルール作成」なのか

既存のルール(`no-console` など)を並べるだけでは、ビジネスロジックの制約は守れません。カスタムルールを作ることは、チームに対して「言語仕様を拡張する」ことと同義です。

AST(抽象構文木)という設計図を読む

ESLintはソースコードを解析し、プログラムの構造をツリー状のデータ(AST)に変換します。カスタムルール作成とは、このツリーを巡回(Visitorパターン)し、特定のノードを見つけた瞬間に「警告(Report)」を発するプログラムを書く作業です。

[AST Explorer](https://astexplorer.net/) を開き、対象のコードを貼り付けてみてください。自分たちが禁止したいコードが、どのノード(例: `CallExpression`, `MemberExpression`)として表現されているかを確認する。これが全ての出発点です。

—

2. 実践:プロジェクト固有の「禁止ルール」を作る

例えば、「特定の非推奨なユーティリティ関数を、特定のファイル以外で呼び出すことを禁止する」ルールを作ります。

カスタムルール実装の雛形

`eslint-rules/no-deprecated-util.js` として以下を配置します。

module.exports = {
create(context) {
return {
// CallExpressionノード(関数呼び出し)をフックする
CallExpression(node) {
// 呼び出されているのが “deprecatedUtil” か確認
if (node.callee.name === ‘deprecatedUtil’) {
// 禁止したい旨を警告する
context.report({
node,
message: ‘deprecatedUtilは廃止予定です。代わりにNewUtilを使用してください。’,
});
}
},
};
},
};

これを `.eslintrc.js` で読み込みます。

module.exports = {
// ローカルルールを読み込むためのプラグイン設定
plugins: [‘local-rules’],
rules: {
// 自作ルールを適用
‘local-rules/no-deprecated-util’: ‘error’,
},
};

この設定により、CI上で非推奨コードが混入した瞬間にビルドが落ちるようになります。「レビューで指摘して修正を待つ」という数時間のラグが、瞬時に解消されます。

—

3. 開発効率を極限まで引き上げる「神設定」と運用術

カスタムルールだけでは不十分です。日常のコーディング体験を劇的に変える設定を共有します。

神プラグイン:`eslint-plugin-perfectionist`

importの順序やオブジェクトのプロパティ順序を自動でソートするプラグインです。これを導入すると、Gitのコンフリクトが激減します。「なんとなくの並び順」を巡る不毛な議論をIDEに委ねてください。

究極の `.eslintrc.js` 構成例

チーム開発において、設定は「階層化」と「自動修正」が鍵です。

module.exports = {
extends: [
‘eslint:recommended’,
‘plugin:@typescript-eslint/recommended’,
‘plugin:prettier/recommended’ // Prettierとの競合を排除する必須設定
],
rules: {
// 「警告」ではなく「エラー」に強制することで、緩みを許さない
‘@typescript-eslint/no-explicit-any’: ‘error’,
// 未使用変数は即座に削除対象として赤線を引く
‘no-unused-vars’: [‘error’, { argsIgnorePattern: ‘^_’ }],
},
// CI/CDでキャッシュを活用し、検証速度を数倍に引き上げる
// lint実行時に –cache を付与するのが鉄則
};

—

4. チームへの浸透:共有のステップ

ルールを強制する際、最も重要なのは「なぜこのルールが必要か」というコンテキストの共有です。

1. PRでの解説: 新ルールを追加する際は、必ず「なぜそのノードを禁止するのか」の理由を `README.md` または Wiki に追記する。
2. 既存コードの負債管理: ルール追加時、既存コードが大量にエラーを出す場合は `eslint-disable` を使わず、`–fix` で自動修正可能な範囲を広げるか、もしくは `eslint-config-prettier` のような段階的な適用戦略をとる。
3. IDEの自動統合: `VS Code` の `.vscode/settings.json` をリポジトリに含め、保存時に自動整形が走る環境をチーム全員に強制する。

{
“editor.codeActionsOnSave”: {
“source.fixAll.eslint”: true // 保存した瞬間にルール違反が直る世界を作る
},
“editor.formatOnSave”: true
}

結論:ツールは「文化」である

カスタムルールを作成することは、単なる技術的な作業ではありません。それは「チームとしてどのようなコードを美しいとし、何をリスクとみなすか」という合意形成そのものです。

ルールが増えるたびに、あなたのチームのレビュー負荷は減り、空いた時間は「より価値のある設計」や「新機能の開発」に充てられます。さあ、今すぐAST Explorerを開き、チームのボトルネックとなっているコードを検知する最初のルールを書いてみてください。その一歩が、数ヶ月後のチームの生産性を劇的に変えるはずです。

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