Pre-commit Hooks、ESLint、Prettierで初歩的なコードミスを未然に防ぐ

Development tutorial - IT technology blog
Development tutorial - IT technology blog

午前2時のタイポから学んだ手痛い教訓

Sentryの通知でスマートフォンが激しく震えました。ホットフィックスをマージした直後、システムで500エラーが多発。45分間ログを調べた結果、原因は急ぎのコピペによる余計な波括弧と未定義の変数(undefined)でした。担当エンジニアはローカルでリンターを実行するのを忘れており、さらに悪いことに「デプロイを急ぐため」にCI/CDがスキップされていました。

チーム内のインデントやカンマの形式を揃えるためだけに午前中を潰したことがある人なら、なぜ私が自動化にこだわるのか理解できるはずです。5人の開発者が参加した最近のプロジェクトで、この自動制御フローを導入したところ、プルリクエスト(PR)での不毛なコードフォーマットに関する議論を80%削減できました。すべてはコードが個人のPCを離れる前に、機械によって綺麗に処理されます。

枕を高くして眠るための3つのツール

常にクリーンなコードを維持するには、多層的な管理システムが必要です。サーバーにプッシュしてからチェックするのではなく、ローカル環境の「入り口」でエラーを阻止します。

  • ESLint: プロの校正者のような役割を果たします。未定義の変数やセキュリティリスクのあるコードなど、ロジック上のエラーを指摘します。
  • Prettier: 「美容師」のような存在です。コードの正誤ではなく、チームで合意したフォーマットに従って、すべてのファイルが整列していることを保証します。
  • Husky & Lint-staged: これらは「門番」の役割を担います。git commitを実行すると、Huskyがlint-stagedを起動し、変更されたファイルに対してESLintとPrettierのチェックを強制します。エラーがある場合、コミットは即座に拒否されます。

ゼロからのセットアップ手順

Node.jsやReactのプロジェクトを想定しています。この仕組みをスムーズに動かすための設定は、わずか10分ほどで完了します。

ESLintとPrettierのインストール

まず、必要なパッケージをインストールします。2つのツールのルールが衝突しないように、eslint-config-prettierを併用します。

npm install -D eslint prettier eslint-config-prettier eslint-plugin-prettier

次に、設定ファイル.eslintrc.jsonを作成します。これは実際のプロジェクトで私がよく使用する標準的な構成です:

{
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:prettier/recommended"
  ],
  "rules": {
    "no-console": "warn",
    "no-unused-vars": "error"
  }
}

共通のスタイルを定義するために.prettierrcも忘れずに作成しましょう。私のチームではシングルクォートを優先し、セミコロンを多用しない設定にしています:

{
  "semi": true,
  "tabWidth": 2,
  "singleQuote": true,
  "trailingComma": "es5"
}

Huskyの有効化 – チェックの自動化

ツールをインストールしても、強制力がなければ忘れ去られてしまいます。Huskyを使えば、Git Hooksを通じてこのプロセスを自動化できます。

npx husky init && npm install

このコマンドにより.huskyディレクトリが作成されます。ただし、ファイル数が多いプロジェクトでコミットのたびに全ファイルをスキャンすると非常に時間がかかります。最適化のためにlint-stagedが必要です。

Lint-stagedによるパフォーマンスの最適化

コミット対象(staged)のファイルのみをチェックするようにlint-stagedをインストールします:

npm install -D lint-staged

package.jsonに以下の設定を追加します:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

最後に、.husky/pre-commitファイルを更新してlint-stagedを呼び出すようにします。これで、コミットするたびにPCが自動的に仕事をしてくれるようになります。

実践:機械がエラーを指摘する瞬間

未使用の変数があり、フォーマットが乱れたapp.jsを作成して試してみましょう。git commit -m "feat: update"を入力すると、ターミナル for スキャンが実行されます。ESLintがno-unused-varsエラーを検出した場合、コミット操作はブロックされます。コードを綺麗に修正しない限り、先へ進めません。一方で、改行のミス程度であれば、Prettierが自動的に修正した上でコミットを許可してくれます。

経験から得た教訓:最初から厳しくしすぎない

私は以前、導入初日からあまりにも多くの厳格なルールを適用して失敗したことがあります。チームメンバーが頻繁にブロックされ、ストレスから--no-verifyを使ってチェックを回避しようとする事態になりました。私のアドバイスは、まずランタイムエラーを防ぐための基本的なルールから始めることです。その後、チームで話し合いながら、スタイルのルールを徐々に増やしていくのがベストです。

結び

Pre-commit Hooksの設定には15分もかかりませんが、そこから得られる価値は非常に大きいです。コードレビューの時間を大幅に節約し、初歩的なミスによる本番環境でのトラブルを防ぐことができます。コードの品質が自動的かつプロフェッショナルに担保されるエンジニアリング文化を築いていきましょう。

Share: