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 .huskylefthook のインストール
次に、lefthook をインストールします。
npm install lefthook --save-devlefthook.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 の組み合わせはまだまだ多そうですが、大規模ブロジェクトではかなり大きく実行速度に差がでるようなので積極的に提案していきたいと思います。