Monorepo で husky + biome を設定した備忘録
Monorepo 環境で husky と Biome を動かしてみたのでその備忘録です。
やってみてから気づきましたが、Monorepo 環境でやるなら Lefthook を使った方が楽そうです。
一応 husky でもできるということでこの記事は続けます。
ちなみに、Git Hooks を利用して Biome で動かしたい場合のガイドは https://biomejs.dev/recipes/git-hooks/#_top にありました。
もし本記事の内容について誤りがあればご指摘いただけますとありがたいです 🙇
設定の流れ
Biome の設定後、husky を利用して commit 時に Biome が動くようにします。
モノレポの構成について
以下のように、packages
配下にモノレポ構成で管理したいパッケージを置いています。
パッケージマネージャは pnpm です。
ルートディレクトリ名は monorepo-husky-and-biome
としています。
monorepo-husky-and-biome
├── package.json
├── packages
│ ├── packages-a
│ ├── packages-b
│ └── packages-c
└── pnpm-workspace.yaml
packages
配下のパッケージをサブパッケージと呼んでいくことにします(正しい呼称かわかってないです 🙇)。
Biome の設定
Biome v2 でモノレポでの使い勝手がよくなったらしく、Biome の設定をルート直下においてそれをサブパッケージで継承できるようになっています。
Biome のインストール
Biome のインストールは公式のガイド通りに行います。
ルート直下で Biome をインストールするためのコマンドを実行します。
pnpm add -D -E @biomejs/biome
執筆時点で Biome v2.1.1 がインストールされています。
Biome の設定を初期化するコマンドを実行します。
pnpm exec biome init
ルート直下に biome.json
が生成されているはずです。
モノレポ用に Biome を設定
Biome 公式のモノレポ利用時のガイドを参照しつつ行います。
まず、各サブパッケージに biome.json
を下記の内容で配置していきます。
{
"root": false,
"extends": "//"
}
大事なのは "extends": "//"
という部分です。extends
プロパティでは指定した設定ファイルを継承してくれるため、今回 //
とすることでルート直下の ./biome.json
を継承するように指定しています。
ここまでで モノレポで Biome を動かすための設定は完了です。
Biome の動作確認
問題ないか動作確認をします。
ここは飛ばしても大丈夫です。
packages/packages-a/
に index.ts
を作成し、Biome が Lint してくれる以下のコードを書きます。
let num = 10;
console.log(num);
Recommended rules に含まれている const
を使おうというルールの指摘が当たるコードになっています。
packages/packages-a/
に移動し、index.ts
をチェックさせます。
pnpm exec biome check index.ts
設定がうまくいっていれば以下のように Lint された内容が出力されるはずです。
index.ts:1:1 lint/style/useConst FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This let declares a variable that is only assigned once.
> 1 │ let num = 10;
│ ^^^
2 │
3 │ console.log(num);
ℹ 'num' is never reassigned.
> 1 │ let num = 10;
│ ^^^
2 │
3 │ console.log(num);
ℹ Safe fix: Use const instead.
1 │ - let·num·=·10;
1 │ + const·num·=·10;
2 2 │
3 3 │ console.log(num);
Checked 1 file in 1431µs. No fixes applied.
Found 1 warning.
確認が済んだので husky の設定に移ります。
husky の設定
husky を利用して biome を動かすための設定をしていきます。
なお、husky 単体だけでは具体的な動作を起こせないので lint-staged と組み合わせて使います。
husky はセキュリティ上の都合で、モノレポのような環境で親ディレクトリに遡ってのインストールができないらしいです。
そのため husky を初期設定する場合、.git
があるパッケージのルートディレクトリでコマンドを実行しないといけません。
なので、一般的な husky の設定のように package.json
に "prepare": "husky"
とするだけでは動いてくれません。
そこでどうするかというと .git
のあるディレクトリに移動してから husky コマンドのオプションにサブパッケージのパスを指定するとできます。
これは公式ドキュメントにも記載がありました。
モノレポ用の設定をするにあたり以下の記事を参考にさせていただきました。
- https://zenn.dev/ryoooosk/articles/8901e8a3f25a38
- https://qiita.com/les-r-pan/items/c03f12bc1693983daa70
モノレポ用に husky & lint-staged を設定
まず husky と lintstaged をインストールします。
パッケージのルートディレクトリでインストール用のコマンドを実行します。
pnpm add -D husky lint-staged
続いて以下のように、packages/packages-a/package.json
の scripts
プロパティの "prepare" のところにコマンドを追加します。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "prepare": "cd ../.. && husky packages/packages-a/.husky"
},
pnpm run prepare
を実行して husky をインストールします。
インストールできれば、 packages/packages-a/
配下に .husky
というフォルダができているはずです。
続いて lint-staged を設定して commit 時に Biome が動くようにします。
package.json
に lint-staged
関連の記述を入れます。
+ "lint-staged" : {
+ "*.ts": "biome check --write"
+ },
*.ts
で拡張子が ts
のファイルを対象に、右側に書いてある biome check --write
コマンドを実行してくれます。
次に .husky
の中に pre-commit
というファイルがあるので、それを編集します。
もしなかったら作成してください。
cd packages/packages-a
pnpm run lint-staged
モノレポでは、.git
があるパッケージのルートディレクトリでコマンドが実行されます。
なので、今回の対象ディレクトリである packages/packages-a
まで移動させるために 1 行目の記述をしています。
2 行目では先ほど設定した lint-staged を動かしています。
ここまでで husky + lint-staged を利用して Biome を動かせるようになったので、index.ts
を commit してみます。
git add index.ts
git commit -m "biome が動くかどうかテスト"
commit 差分に .ts
ファイルが含まれていて husky が動いた場合は以下のように四個ぐらいのチェックマークが出てくれます。
✔ Backed up original state in git stash (063ed90)
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
設定が上手くいっていない場合には → No staged files found.
と、対象ファイルがないと言われる場合があります。
packages-b
で *.ts
を commit した場合の挙動
packages-a
での設定が出来たので、それが他のサブパッケージに影響を及ぼさないか確認してみます。
husky の設定をしていない packages/packages-b
に index.ts
を追加して commit してみると → No staged files found.
となりました。
husky が動くのは意外でしたが packages/packages-a
の設定が伝播していないので問題ない挙動です。
git
コマンドを叩く場所で挙動が変わりそうですが、ルートディレクトリでも packages/packages-b
でも同様の表記なので husky 自体はどこでも動くのかもしれない。
理解が浅いですがここは深追いしません……。
ルートディレクトリから packages/packages-a
の commit を打つとちゃんと設定した通りに Biome が動いてくれるので多分挙動的に問題はないのかも。
私は Lefthook に乗り換え予定なので実際の使用感を試してみてここら辺の認識を深めるのは多分しなそうです。気になる方はお手数ですがご自身で検証していただけるとありがたいです 🙇
終わりに
Monorepo 環境で husky + lint-staged + Biome を利用して commit 時に Lint してくれる設定については以上のとおりです。
備忘録なので至らぬところが多数と思います。間違いなどあれば宜しければご指摘いただけるとありがたいです。
参照させていただいた記事
Discussion