Hiratake Web ロゴ

Husky + lint-staged からLefthookへ移行する

投稿した日
更新した日
書いたひと
icon
ひらたけ

Lefthook という Git フックを管理するツール の存在を知ったので使ってみることに。Git でコミットするときにステージングしたファイルに対して Linter や Formatter を実行するとか、Push するときにテストを実行するとかを、このツールひとつで出来るらしい。

これまではずっと Huskylint-staged を使って、コミット時にコミットメッセージをチェックしたりステージングしたファイルに ESLint や Prettier などの Linter と Formatter を実行していたのですが、これを Lefthook へ移行してみたので、備忘録的な感じで書いていこうと思います。

環境

Lefthook は Node.js が動作する環境がなくても利用できますが、今回は Husky + lint-staged からの移行なので Node.js のパッケージを使っているリポジトリで作業を行います。

移行前となる環境で使っていた Husky と lint-staged のバージョンは以下の通りです。

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 でインストールして利用します。

インストールする前に、ドキュメントによると .npmrcside-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-commitpre-push などの Git フックそれぞれに対して、commands に実行するコマンドを設定します。commands の下にある linterformatter の部分は任意の名前を指定できます。

commitlint を設定する場合、Husky では pnpm commitlint --edit ${1} を指定していましたが、Lefthook では $ を外して pnpm commitlint --edit {1} と設定する必要があるようです(このへんあまりよく分からない)。

ここまで設定して、試しにコミットをしてみると、無事コミットメッセージのチェックや Linter と Formatter が実行されました。


Husky + lint-staged から Lefthook へ移行してみましたが、1 つのツールで同じことが出来るのは設定ファイルがあちこちに分散しなくて良いなと思いました。

lefthook-local.yml というファイルを作成して全体の設定を上書きすることも可能。まだ複数人で触るリポジトリで Lefthook を使っていないですが、特定の作業者の環境では Linter は実行するけど Formatter は実行しない、みたいなことが出来るのも便利そうです。