Husky + lint-staged からLefthookへ移行する
- 投稿した日
- 更新した日
- 書いたひと
- ひらたけ
Lefthook という Git フックを管理するツール の存在を知ったので使ってみることに。Git でコミットするときにステージングしたファイルに対して Linter や Formatter を実行するとか、Push するときにテストを実行するとかを、このツールひとつで出来るらしい。
- Introduction - Lefthook Documentation
- evilmartians/lefthook: Fast and powerful Git hooks manager for any type of projects.
これまではずっと Husky と lint-staged を使って、コミット時にコミットメッセージをチェックしたりステージングしたファイルに ESLint や Prettier などの Linter と Formatter を実行していたのですが、これを Lefthook へ移行してみたので、備忘録的な感じで書いていこうと思います。
環境
Lefthook は Node.js が動作する環境がなくても利用できますが、今回は Husky + lint-staged からの移行なので Node.js のパッケージを使っているリポジトリで作業を行います。
移行前となる環境で使っていた Husky と lint-staged のバージョンは以下の通りです。
- Husky - 9.1.7
- lint-staged - 15.3.0
Husky と lint-staged をアンインストールする
まずは元々 Git のフックを利用するために使っていた Husky と、Git でステージングしたファイルにだけ Linter や Formatter を実行するために導入していた lint-staged をアンインストールします。私は普段 pnpm を使用しているので、以下コマンドを実行します。
$ pnpm remove husky lint-staged
Husky を利用する際、pnpm exec husky init
コマンドによってセットアップを行いますが、これにより Git フックで実行するスクリプトを配置するディレクトリのパスが変更されます(.git/hooks
から .husky/_
へ)。元々 Husky を利用していた環境なので、当然のことながらパスを変更されているため、これを戻します。
Git のドキュメントによると、設定ファイルの core.hooksPath
という値にフックのディレクトリを指定するとのこと。
対象となるリポジトリの .git/config
ファイルから core.hooksPath
の設定を手動で削除するか、以下コマンドを実行して、変更されていたパスを元に戻します。
$ git config --unset core.hooksPath
最後に、Husky と lint-staged で使用していたファイルやディレクトリを削除します。今回は .husky
ディレクトリとその中身、.lintstagedrc.json
を削除しました。
Lefthook をインストールする
真っ赤な左フックのアイコンがカッコいい、Lefthook をインストールします。Ruby や Go などでも利用が可能ですが、今回は元々利用していた Husky や lint-staged と同じく pnpm でインストールして利用します。
インストールする前に、ドキュメントによると .npmrc
に side-effects-cache = false
を指定しておく必要があるとあるので追記しておきます。その後、以下コマンドを実行して Lefthook をインストールします。
$ pnpm add -D lefthook
Husky の場合はインストール後に手動で pnpm exec husky init
を実行したり、package.json
のスクリプトのところに prepare
のコマンドを追加したりする必要がありましたが、Lefthook はパッケージのインストール時に自動で lefthook install
が実行されてセットアップが完了します。
また、Lefthook をインストールすると、自動的に Lefthook の設定ファイルである lefthook.yaml
ファイルがリポジトリのルートに作られます。ご丁寧にファイル内のコメントに設定の例が用意されているので、そちらを参考に設定をします。
以下は今回設定したもの。コミット時にステージングされているファイルに対して ESLint と Prettier を実行するのと、コミットメッセージのチェックとして commitlint を実行するのを設定しています。
pre-commit:
parallel: true
commands:
linter:
glob: '*.{js,ts,jsx,tsx,cjs,cts,mjs,mts,vue}'
run: pnpm eslint --fix {staged_files}
stage_fixed: true
formatter:
glob: '*.{html,css,scss,js,ts,jsx,tsx,cjs,cts,mjs,mts,vue,json,yml,yaml}'
run: pnpm prettier -w {staged_files}
stage_fixed: true
commit-msg:
commands:
commitlint:
run: pnpm commitlint --edit {1}
pre-commit
や pre-push
などの Git フックそれぞれに対して、commands
に実行するコマンドを設定します。commands
の下にある linter
や formatter
の部分は任意の名前を指定できます。
commitlint を設定する場合、Husky では pnpm commitlint --edit ${1}
を指定していましたが、Lefthook では $
を外して pnpm commitlint --edit {1}
と設定する必要があるようです(このへんあまりよく分からない)。
ここまで設定して、試しにコミットをしてみると、無事コミットメッセージのチェックや Linter と Formatter が実行されました。
Husky + lint-staged から Lefthook へ移行してみましたが、1 つのツールで同じことが出来るのは設定ファイルがあちこちに分散しなくて良いなと思いました。
lefthook-local.yml
というファイルを作成して全体の設定を上書きすることも可能。まだ複数人で触るリポジトリで Lefthook を使っていないですが、特定の作業者の環境では Linter は実行するけど Formatter は実行しない、みたいなことが出来るのも便利そうです。