Gemcook Tech Blog
🤛

Lefthookを使ってみたい!

2024/09/13に公開

はじめに

皆さん、どうも!

今日は私が最近知って、実際に使ってみたツール「Lefthook」についてお話しします。

Lefthookは、コードの品質管理や開発プロセスの効率化に役立つツールです。formatやlintの調整など、ローカルで確認したいCI/CDをリモートにコードをあげる前に自動で確認できるツールです。使ってみると、導入コストも高くなくてしかも並列でCI/CDできるから開発作業がスムーズになって驚きました。

今回感じたLefthookの魅力をお伝えできればと思います!!

https://github.com/evilmartians/lefthook/tree/master

Lefthookとは?

git hooks managerです。他の代表例で言うとHuskyになりますね。あの狼のやつ🐺

commit前やpush前にスクリプトを自動で実行することができるツールです。

代表的な使い方で言うと、lint-stagedと組み合わせてPrettierとESlintを実行させてformatやlintの調整で使われることが多いと思います。プロジェクト全体で開発していても各個人の設定が違うとみんなバラバラのフォーマットになり毎回余計な差分がPRで出てしまってレビューする側が大変ですよね😫

そんな時にLefthookを使うことで、PRを作成する前にコードのスタイルをチーム全体で一貫性を保つことができます!

git hooksについてはこちらの方がわかりやすかったので、確認してみてください!
https://qiita.com/noraworld/items/c562de68a627ae792c6c

なぜ導入したいのか

私がLefthookを導入した理由は、主に以下の2点です:

信頼性の高い推奨

Biomeの公式ドキュメントでLefthookが紹介されているのを見て、信頼性の高いツールだと感じました。公式が書いているというのがそのツールの価値を裏付けるものでもあるのかなと思います。

新しいツールへの挑戦

Huskyは今でも問題なく使えると思います。でも自分の中で開発者として常に新しいツールに触れ、より良い選択肢を探ることは大切だと考えていていて、その中でLefthookの存在を知り触ってみたいと思いました。
(アイコンとかユニークですし🥊)

https://biomejs.dev/ja/recipes/git-hooks/#lefthook

HuskyとLefthookの違いは?

HuskyとLefthookにはいくつかの違いがあります。まず、HuskyはNode.jsで作られているので、JavaScriptプロジェクトとの相性が良いと言えます。一方、LefthookはGoで作られているので、動作が速いといったのが特徴です。

設定ファイルの形式も違います。HuskyはJSONを使いますが、LefthookはYAMLを使います。

特に便利なのは、Lefthookがコマンドを並列で実行できることです。これにより、フックの実行時間を大幅に短縮できます。大きなプロジェクトでは、この並列実行がとても役立ちますね!

使い方

インストール

まずはbrewでlefthookをインストールしましょう!

terminal
brew install lefthook

そのあとプロジェクトに追加します。(bunのところはお使いのpackage managerに合わせてください)

terminal
bun add lefthook

追加するとrootにlefthook.ymlが生成されると思います。

中身は以下のEXAMPLEが入ってます。親切で良い!!

EXAMPLE
lefthook.yml
# EXAMPLE USAGE:  
#  
#   Refer for explanation to following link:  
#   https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md  
#  
# pre-push:  
#   commands:  
#     packages-audit:  
#       tags: frontend security  
#       run: yarn audit  
#     gems-audit:  
#       tags: backend security  
#       run: bundle audit  
#  
# pre-commit:  
#   parallel: true  
#   commands:  
#     eslint:  
#       glob: "*.{js,ts,jsx,tsx}"  
#       run: yarn eslint {staged_files}  
#     rubocop:  
#       tags: backend style  
#       glob: "*.rb"  
#       exclude: "application.rb|routes.rb"  
#       run: bundle exec rubocop --force-exclusion {all_files}  
#     govet:  
#       tags: backend style  
#       files: git ls-files -m  
#       glob: "*.go"  
#       run: go vet {files}  
#   scripts:  
#     "hello.js":  
#       runner: node  
#     "any.go":  
#       runner: go run

書き方

今回は以下に用意した例を用いて説明します。

まずは、pre-commit pre-pushに対してコマンドを設定していきます。

lefthook.yml
pre-commit:
  commands:
    format:
      glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
      run: bunx biome check --apply --no-errors-on-unmatched --files-ignore-unknown=true ./src && git update-index --again

pre-push:
  commands:
    format:
      glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
      run: bunx biome check --no-errors-on-unmatched --files-ignore-unknown=true ./src

基本的にcommands以下に設定していきます。commands以下が実行されるイメージです。

formatの部分は任意で名前を変えることができます。今回はコードを整形したいのでformatと名付けてます。

  • globでファイルを指定します。

  • runで走らせたいコマンドを書きます。今回の場合はBiomeを使いたいので書いてます。

基本はこれだけです。pre-pushも基本的に同じ要領でやれば問題ありません。

並列で走らせる

ここから、Lefthookでしかできない並列にhookを走らせる方法です。

lefthook.yml
pre-commit:
  parallel: true # ここに書く
  commands:
    format:
      tags: format
      glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
      run: bunx biome check --apply --no-errors-on-unmatched --files-ignore-unknown=true ./src && git update-index --again
    tsc:
      tags: tsc
      glob: "*.{ts,cd.mts,tsx}"
      run: bunx tsc --noEmit

paralleltrueにすることでcommands以下に書かれている並列にコマンドが走ります。defaultは基本的にfalseになっています!

biomeでフォーマットをしてその間にtscを実行することができますね!これはかなりプロジェクトによっては時間が短縮されるのではないでしょうか?

また、直列に実行させたいときやコマンドでエラーが起きた時に停止させたい場合は、parallelと同じ箇所にpiped: trueを設定することで可能です。

特定のコマンドをスキップさせたい

並列に走らせたいけど今回は特定のコマンドは必要ないなって時は以下のようにLEFTHOOK_EXCLUDEtags名を指定してあげるとスキップすることができます。

LEFTHOOK_EXCLUDE=tsc git commit -m "Skip command"

関連PR

https://github.com/evilmartians/lefthook/issues/295

終わり

Lefthookを使ってみて、率直に言って本当に良かったです。開発プロセスが格段にスムーズになり、楽になりました。

新しいツールを試すのは少し勇気がいりますが、今回はその一歩を踏み出して良かったと感じています!

皆さんも、興味が出たらぜひLefthook使ってみてください。

Gemcook Tech Blog
Gemcook Tech Blog

Discussion