Husky & lint-stagedで「汚いコード」を一掃し、コミットを標準化する

Git tutorial - IT technology blog
Git tutorial - IT technology blog

「バグ修正」の悪夢とバラバラなコーディングスタイル

プルリクエスト(PR)を開いたときに、インデントがバラバラだったり、シングルクォート(’)とダブルクォート(”)が混在していたりするのは、決して気持ちの良いものではありません。さらに最悪なのは、Gitの履歴を確認したときに「fix」や「update」、さらには「abcxyz」といった意味のないコミットメッセージが並んでいるのを目にすることです。

私が8人のチームを率い始めたばかりの頃、毎日少なくとも30分は「Prettierを実行して」「これLintが通っていないよ」といった指摘に費やしていました。こうした些細なミスのせいで重要な変更点が見えにくくなり、ロジックのレビューが苦痛になっていました。

個人の自覚に期待しすぎてはいけません。自覚は締め切りまでの時間に反比例するものです。最善の策は自動化することです。コードが標準に達していなかったり、コミットメッセージの形式が間違っていたりする場合、Gitが即座にコミットを拒否するようにします。ここでHuskyとlint-stagedの出番です。

クイックスタート:5分で完了するセットアップ

Node.jsプロジェクト(React、Vue、NestJSなど)に適用する手順は以下の通りです。わずか数コマンドで、献身的な「門番」を配置できます。

ステップ1:Huskyの初期化

Huskyを使えば、複雑な隠しファイルを直接触ることなく Gitフックを操作できます。

npx husky init && npm install

このコマンドは .husky フォルダを作成し、package.jsonprepare スクリプトを追加します。

ステップ2:lint-stagedのインストール

プロジェクト全体をスキャンする(非常に遅い)代わりに、lint-staged は変更されたファイルのみをチェックします。

npm install --save-dev lint-staged

ステップ3:チェックルールの設定

自動コマンドを定義するために、package.json に以下の設定を追加します。

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

ステップ4:フックの有効化

.husky/pre-commit ファイルを開き、内容を以下に書き換えます。

npx lint-staged

今後、git commit を実行するたびにHuskyが lint-staged を呼び出します。自動的にフォーマットの修正とLintチェックが行われ、自動修正できないエラーが検出された場合はコミットがブロックされます。

なぜHuskyとlint-stagedの両方が必要なのか?

「Huskyだけで十分ではないか?」という疑問を持つ方もいるでしょう。その答えはパフォーマンスにあります. 1,000ファイルある大規模なプロジェクトでプロジェクト全体にLintを実行すると約2分かかります。しかし、lint-staged を使えば、git add した2〜3ファイルのみをスキャンするため、わずか2秒に短縮されます。コミットの体験が格段にスムーズになります。

応用編:コミットメッセージの標準化

Gitの履歴をオープンソースライブラリのようにプロフェッショナルな見た目(例:feat: add login)にするには、commitlint を追加でインストールしましょう。

クイックインストール

npm install --save-dev @commitlint/config-conventional @commitlint/cli

設定ファイルの作成

ルートディレクトリに commitlint.config.js ファイルを作成します。

module.exports = { extends: ['@commitlint/config-conventional'] };

メッセージチェック用フックの追加

echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

もし「完了」といった内容でコミットしようとすると、Gitは subject may not be empty というエラーを表示します。これにより、type: description という正しい形式で書くことが強制されます。

導入における実践的なアドバイス

これらのツールを多くのプロジェクトに導入してきた経験から、3つの重要な注意点を挙げます。

  • 最初はルールを緩めにする: 最初から厳格なESLintルールを適用しすぎないようにしましょう。まずはPrettierでフォーマットを統一することから始め、徐々にコードロジックの制約を強めていくのが得策です。
  • 「バイパス」権限: 本番環境のホットフィックスなど緊急事態でバグを修正する必要がある場合は、--no-verify フラグを使用してチェックをスキップできます。ただし、乱用は禁物です。
  • チーム内での同期: Huskyを更新した後は、チームメンバーに npm install を実行するよう伝えてください。そうしないと、彼らの環境でフックが動作しません。

このプロセスを導入して以来、フォーマットの違いによるマージコンフリクトが80%減少しました。レビュアーも、カンマの位置を気にする代わりにプログラミングのロジックに集中できるようになり、負担が軽減されました。

ちょっとしたTips

サーバーにプッシュされるコードが常に正しく動作することを保証したいですか? Gitの履歴をオープンソースライブラリのようにプロフェッショナルな見た目に保つことは重要ですが、さらに pre-push フックを追加してユニットテストを実行するようにしましょう。

echo "npm test" > .husky/pre-push

これにより、CI/CDシステムの負荷を軽減し、共通環境を「壊す」ことを未然に防ぐことができます。

Huskyとlint-stagedの設定には5分しかかかりませんが、得られるメリットは計り知れません。ぜひ個人のプロジェクトに導入したり、次のミーティングでチームに提案したりしてみてください!

Share: