husky と lint-staged でコミット前に Linter とフォーマットを自動実行するようにした話

husky と lint-staged を導入してコミット前に ESLint と Prettier を自動実行するようにしたら、コードレビューでフォーマット系の指摘がほぼゼロになりました。セットアップ手順と使ってみた感想をまとめます。

🙌 結論から

husky と lint-staged を入れてからコミット前に自動でリントとフォーマットが走るようになり、コードレビューでのフォーマット系の指摘がほぼゼロになりました!

「インデントが崩れている」「末尾に余分なスペースがある」という細かい指摘は、機械に任せるべきです。

人間がレビューで確認する時間は、ロジックや設計の本質的なところに集中させたいです。

セットアップ自体は 10 分もあれば終わるので、まだ導入していないプロジェクトがあれば今すぐ入れることをおすすめします(`・ω・´)

👀 導入前の状況

以前のプロジェクトでは、ESLint と Prettier の実行はあくまで手動でした。

「コミット前に忘れずに npm run lint を実行する」というルールだったのですが、作業が立て込んでいるときに忘れてしまうことが何度かありました(´・ω・`)

プルリクを出したあとに「フォーマットが崩れてます」と指摘されると、修正 → 再コミット → 再プッシュと手間がかかります。

こういったミスを仕組みとして防ぎたくて、git hooks の自動化を調べ始めました。

💡 husky と lint-staged のセットアップ

まず必要なパッケージをインストールします。

npm install --save-dev husky lint-staged
npx husky init

npx husky init を実行すると .husky/ ディレクトリが作られ、package.jsonprepare スクリプトも自動で追加されます。

次に .husky/pre-commit ファイルを以下の内容に編集します。

npx lint-staged

これだけです。

続いて package.json に lint-staged の設定を追加します。

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

この設定で、ステージング済みのファイルにだけ ESLint と Prettier が実行されます。

プロジェクト全体にリントを走らせるより格段に速く終わるのが lint-staged の便利なところです(^^)

あとはコミットするだけで、前回以降に変更したファイルに対してだけリントとフォーマットが自動で走ります!

✨ 実際に使ってみた感想

使い始めてすぐ「これは入れてよかった」と感じました。

一番大きな変化は、フォーマットについてまったく気にしなくてよくなったことです。

コミット時に自動でスタイルが揃うので、エディタのフォーマット設定を細かく合わせなくても問題ありません。

ただし、ESLint のエラーが出るとコミット自体がブロックされます。

最初はびっくりするかもしれませんが(・_・;)、逆に言えば問題のあるコードがリポジトリに入り込まないので、長期的には安心感があります。

チームで使うと特に効果的で、「フォーマットは機械が自動で揃えてくれる」という共通認識が生まれます。

レビュアーが本質的なロジックの部分に集中できるようになるのは、開発チームにとってかなりありがたいです!

個人開発でも、数ヶ月後に自分が書いたコードを読み返すとき、スタイルが揃っているだけでかなり読みやすく感じます。

📝 commitlintでコミットメッセージも自動チェックする

コードのフォーマットは自動化できたんですが、しばらくするとコミットメッセージの書き方がバラバラなことが気になり始めました。

「fix bug」「update」「wip」のような投げやりなメッセージが混ざると、あとで git log を眺めても何が変わったのか分かりにくくなります。

そこで commitlint を使って、Conventional Commits(feat: fix: のような接頭辞をつける規約)に沿っているかをコミット時にチェックするようにしました。

npm install --save-dev @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
export default {
  extends: ['@commitlint/config-conventional'],
};

commit-msg という、コミットメッセージ入力後に発火するフックを追加します。

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

これで feat: ユーザー一覧にページネーションを追加 のような書き方は通り、update stuff のような曖昧なメッセージはコミット自体がブロックされるようになりました(・∀・)

最初は「メッセージまで縛られるのは窮屈かも」と思っていたんですが、実際にやってみるとコミット履歴がそのままリリースノートの下書きとして使えるレベルになって、かなり快適でした。

pre-commit でコードの中身を、commit-msg で説明の書き方を、両方自動チェックする体制にしてから、リポジトリ全体の見通しがさらによくなった感覚があります!

パパ系Webエンジニア〜愛用ガジェット一覧 🛍️

この記事を書いている作業環境のガジェットを楽天ROOMにまとめています ✨ 在宅エンジニアのデスク作りの参考にどうぞ 🙌

🙌 まとめ

husky と lint-staged の組み合わせは、導入コストが低い割に効果の大きいツールです!

  • コミット前に自動でリントとフォーマットが走る
  • lint-staged でステージング済みファイルだけを対象にするので速い
  • レビューでのフォーマット指摘がほぼゼロになる

セットアップは 10 分程度で終わります。

まだ導入していないプロジェクトがあれば、ぜひ今日試してみてください🙌

※ 各ツールのバージョンや機能は今後も更新されます。最新情報は Husky公式ドキュメント をご確認ください👀