「バグ修正」の悪夢とバラバラなコーディングスタイル
プルリクエスト(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.json に prepare スクリプトを追加します。
ステップ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分しかかかりませんが、得られるメリットは計り知れません。ぜひ個人のプロジェクトに導入したり、次のミーティングでチームに提案したりしてみてください!

