コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

lefthook を導入してみた話

こちらは「コドモン Advent Calendar 2024」の 10日目の記事です。

qiita.com

こんにちは。プロダクト開発部の河野です。
今回は、最近チームに導入した lefthook の使い勝手が良かったので、紹介したいと思います。

lefthook とは

Git フックの管理ツールで、Git のコミットやプッシュ操作時に任意の処理を走らせることができるツールです。

Fast. It is written in Go. Can run commands in parallel.
Powerful. It allows to control execution and files you pass to your commands.
Simple. It is single dependency-free binary which can work in any environment.

主な特徴は 「高速」、「強力」、「シンプル」と記載されています。
実際に導入してみたところ、その管理のしやすさも実感できたため、今回はその辺りを紹介できればと思います。

github.com

前提

導入したリポジトリの構成や技術スタック、ツール群は以下の通りです。

  • 技術スタック: React、TypeScript
  • パッケージ管理: pnpm
  • リンター、フォーマッター: biome

リポジトリ構成

├...
├──services
  ├──serviceA
  │  ├──api
  │  └──frontend ← 導入箇所
  ├──serviceB
  ├──serviceC
├...
├──package.json
├──biome.json
└──pnpm.workspace.yaml

service フォルダ配下に各マイクロサービスが配置されており、それぞれ各チームで管理しています。
パッケージは pnpm でモノレポ管理しており、コードスタイルのルールは Biome で共通ルールを biome.json に定義し、各マイクロサービスでは必要に応じて個別の設定で上書き(オーバーライド)する形で運用しています。

導入内容

上記のリポジトリ構成にある services>serviceA>frontend を対象に 以下の フックを実行させるようにしました。

  1. コミット時に biome の リンターとフォーマッターを実行
  2. コミット時に tsc で型チェックを実行
  3. コミット時に vitest を実行

また、service 共通のフックとして、コミットメッセージに service ディレクトリ名をプレフィックスとして付与する処理も定義しています。

設定の具体例

それでは、実際の設定ファイルを例に定義方法を紹介していきます。
lefthook をインストールすると、lefthook.yml が生成されるため、そちらに定義していきます。

biome の実行

pre-commit:
  commands:
    lint-check:
      root: services/serviceA/frontend/
      glob: "**/*.{ts,tsx}"
      run: pnpm biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off  {staged_files}

pre-commit > commands セクションに実行したいフックを定義していきます。
lint-check は任意のフック名になります。

root で実行ルートのフォルダを指定することができます。 ここで導入対象のフォルダを指定することで、簡単に他のフォルダへの影響を防ぎつつ、特定の範囲でのみチェックを実行することができます。

glob は実行対象のファイルをフィルタリングできます。
root を定義しているため、この場合は services/serviceA/frontend 配下の .ts または .tsx のファイルが対象になります。

run セクションで実際に実行するコマンドを定義します。
pnpm biome と書いていますが、ここも root を定義していれば、特に意識することなく services/serviceA/frontend で定義している package.json のコマンドを参照して実行してくれます。

また、lefthook は {staged_files} の引数で、git のステージに上がっているファイル群を参照することができます。
従来は、lint-staged を別途インストールする場合が多かったですが、lefthook で完結するのも嬉しいポイントですね。

tsc の実行

    type-check:
      root: services/serviceA/frontend/
      glob: "**/*.{ts,tsx}"
      run: pnpm run type-check

biome 実行同様に、services/serviceA/frontend/ の package.json に定義している type-check コマンド(中身 は tsc 実行)を実行しています。

vitest 実行

    vitest:
      root: services/serviceA/frontend/
      glob: "**/*.{ts,tsx}"
      run: pnpm run run-test

こちらも同様ですね。

コミットメッセージ処理

こちらは、既存の githook として、各service で変更されたコミットのメッセージにプレフィックスを付与するシェルが動いていました。

lefthook はシェルの実行も簡単に定義できます。
.lefthook>commit-msg>prepare-commit-msg.sh を配置して、以下のように定義すれば OK です。

commit-msg:
  scripts:
      prepare-commit-msg.sh:
        runner: bash

github.com

まとめ

今回は、lefthook を導入することで、Git フックの設定や管理がスムーズになり、コードの品質を保ちながら効率的に開発を進められる仕組みをご紹介しました。
特に、特定のフォルダに絞った処理の実行や、設定がシンプルで柔軟な点が良いと感じました。
気になった方は、ぜひ一度試してみてください!