Husky, lint-staged から lefthook に乗り換える
はじめに
husky
と lint-staged
は、Git フックを利用してコミットやプッシュのタイミングでコードのフォーマットや静的解析を行うためのツールとして広く使用されています。更に、lint-staged
を使えば、ステージングされたファイルのみに対して処理を適用できるため、セットでよく使われいると認識しています。
しかし、プロジェクトが大きくなるにつれて、husky
の設定や動作が複雑になり、パフォーマンス面での課題も出てくるようで、更に実際にかなり実行速度の違いがあるようです。
この記事では、husky
と lint-staged
から lefthook
に移行する方法を解説します。
Husky, lint-staged と lefthook の違い
項目 | Husky + lint-staged | lefthook |
---|---|---|
言語・依存性 | JavaScript (Node.js 必須) | Go (シングルバイナリ、Node.js 不要) |
設定の柔軟性 | 比較的柔軟だが、設定ファイルが分散しやすい | YAML で一元管理、個人設定も可能 (lefthook-local.yml ) |
パフォーマンス | Node.js 上で動作するためやや遅い | Go で実装されているため高速 |
エコシステムの汎用性 | 主に Node.js 向け | 多言語対応、Node.js 以外でも利用可能 |
なぜ lefthook の方が良さそうなのか?
- チームと共通設定を共有しつつ、個人用のカスタマイズが可能
lefthook
はプロジェクト全体で共通のフック設定(lefthook.yml
)を利用できますが、同時に個人用の設定(lefthook-local.yml
)も可能です。たとえば、特定のメンバーが独自のフックを使いたい場合や、特定のフックを無効化したい場合に柔軟に対応できます。
- 高速で軽量
- Go 言語で書かれているため、
husky
よりも高速に動作します。また、シングルバイナリで動作するため、インストールやセットアップが簡単です。
- Go 言語で書かれているため、
- 多言語対応
- Node.js 以外のエコシステムでも簡単に導入でき、特に多言語混在のプロジェクトや CI/CD 環境で強みを発揮します。
- シンプルな設定
- YAML 形式で設定を一元管理できるため、
husky
+lint-staged
のような複雑な設定ファイルを必要としません。
- YAML 形式で設定を一元管理できるため、
実際に移行する
husky
と lint-staged
のアンインストール
まず、既存の husky
と lint-staged
をアンインストールします。
npm uninstall husky lint-staged
また、.husky
ディレクトリが残っている場合は削除します。
rm -rf .husky
lefthook
のインストール
次に、lefthook
をインストールします。
npm install lefthook --save-dev
lefthook.yml
の作成
lefthook
の設定ファイル lefthook.yml
をプロジェクトルートに作成します。以下は、tsc
, eslint
, prettier
を走らせている例です。pre-commitなので{staged_files}
にてステージングされたファイルにだけ実行されるようにしています。
lefthook.yml
pre-commit:
commands:
type-check:
run: npx tsc --noEmit
eslint:
glob: '*.{js,jsx,ts,tsx}'
run: npx npm run lint --fix --file {staged_files}
prettier:
glob: '*.{js,jsx,ts,tsx}'
run: npx prettier --write {staged_files}
Git フックのセットアップ
以下のコマンドを実行して、lefthook
を Git フックとして登録します。
npx lefthook install
これにより、.git/hooks
ディレクトリに必要なフックが配置され、設定は完了です。
npx lefthook install
実行時に.husky
が自動生成される件
問題の原因
lefthook
をインストールした際に、.husky
ディレクトリが自動生成される場合があります。これは、以前 husky
を使用していたプロジェクトで、Git の設定が変更されていることが原因です。
具体的には、husky
が Git の core.hooksPath
を .husky
に設定している可能性があります。この設定が残っていると、lefthook
も .husky
を使用しようとします。
解決策
以下の手順で問題を解決します。
-
core.hooksPath
の設定を確認・削除git config core.hooksPath
結果が
.husky
の場合、以下のコマンドで設定を削除します。git config --unset core.hooksPath
-
.husky
ディレクトリの削除rm -rf .husky
-
lefthook
の再インストール :npx lefthook install
まとめ
husky
と lint-staged
の組み合わせはまだまだ多そうですが、大規模ブロジェクトではかなり大きく実行速度に差がでるようなので積極的に提案していきたいと思います。