husky(v.8系)をNext.js + Voltaの環境に導入し、GUIからのコミットでも動かす方法

みなさんこんにちは。

TRYTでフロントエンドエンジニアをやったりやってなかったりするやっくんです。

本日はこのテックブログを盛り上げようってことで、ほんとはお酒とかe-sportsとかパン作り、あと陶器とか西遊記について書きたかったのですが、

ここはひとつまじめにエンジニアリングについて書こうと思います(趣味の分布がバグってる)。

で、本題は長いタイトルの通りです。

フロントの資材にhuskyを導入し、GUIからのコミット時にもprecommitを走らせるまでの手順やよくあるエラーなどについて書いていきます。

huskyとは

huskyとはGitのコミットやプッシュなど、特定の動作をトリガーとし任意の処理を自動(強制)的に実行してくれるものです。

『開発作業→コミット(これがトリガー)→ コードの整形処理が走る(ここをhuskyが担う)→ コミットされる』

というような使い方が一般的かなと思います。

チーム開発の際、誰が作業してもソースコードの見た目を担保できるなどのメリットがあります。

で、いろいろ調べていたのですが、huskyに関してはv.3~4, あとたまにv.7についての記事が多く、v.8についてはほとんど情報が見当たらなかったので、

自分の頭の整理も兼ねてここに記します。

(v.3→v.4ほどの仕様の差はv.7→v.8の間にはないのかも。あんまりここ詳しく調べてないです...)


前提

NextとNodeは以下のバージョンです。

Next.js: v.12.0.9
Node: v.16.13.2

Nodeに関しては開発メンバー間でのバージョンの差異をなくすため、Voltaで管理しています。

Voltaを使えばプロジェクトごとにNode.jsのバージョンをpackage.jsonに明示し固定・共有することができるため、非常に便利です。

詳細や導入については下記の記事がわかりやすいかと思います。

zenn.dev

huskyに関してはVoltaを使用していなくても問題なく使うことができます。

目的と理由

そもそもなぜhuskyをいれることになったのかというと、コミット前に強制的にnpm run buildを走らせたかったからです。

開発チーム内での問題として、npm run devを実行しローカル環境で作業を行い、問題なく動作したのでdevelopにマージ。

そうすると自動デプロイが働き、そこで初めてnpm run buildが通らずデプロイが止まる、といったことが多発していたためです。

コミット時にnpm run buildを強制することで、ビルド成功時にはコミットされ、ビルド失敗時にはコミットされないようにすることができます。

手順

1. huskyをインストールする

導入したいプロジェクト先でnpm i husky -Dを実行します。

開発時にしか使わないため、-Dをつけてpackage.jsondevDependenciesに振り分けます。

2. PATHを通す(CLIでGit操作する場合は不要)

GUI(ここではSourceTreeを想定します)からのコミット時にも処理を実行してほしいため、PATHを通す作業を挟みます。

「よっしゃ、huskyの設定できた!意外と簡単やったな〜、さてコミットするやで!...なんであかんのや!!」

と、husky導入者のほとんどがぶつかる壁だと思います。

このエラーが出る仕組みとしては、SourceTreeさん視点に立って考えるとわかりやすいです。

コミット時にnpm run buildしてくれという命令自体は届いておりますが、

SourceTreeからしたら「いきなりそんなこと言われてもnpmってどこで実行したらええんですかい」

となるわけです。

なので、.huskyrcを新規作成しそこにNode(今回はVolta)のPATHを通してあげます。


(補足コーナー)

rcrun commandの略。設定ファイルという意味をもち、いろんなライブラリで~~rcという形で利用されています。

今回は.huskyrcなのでhuskyの設定ファイルを表しており、そこにPATHを通すということになります。

ファイル名の先頭のドットは隠しファイルという意味です。誰にだって隠したいものはあるということです。

(補足コーナーおわり)


こうすることで『SourceTreeでコミット → huskyが実行される → .huskyrcの中を見る → ほなこれ参考にnpm run buildさせてもらうわ』

と、SourceTreeさんも納得してくれるわけです。

2−1. VoltaのPATHを確認する

まずターミナルを起動し、ホームディレクトリで$ open .zshrcを実行してエディターで.zshrcを開きます。

bashを使用している場合は$ open .bash_profileを実行します。

どっちを使ってるかわからないときは、ターミナルのウィンドウの上側を見るとどちらか書いてあるのでそこを見ればOKです。

2-2. PATHをコピペする

.zshrcの中にVoltaのPATHがありました。

export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"

↑見にくすぎわろた、はてなブログでハイライトってどうやるんですかね

こいつをコピーして、そのまま.huskyrcにペースト→保存して終了してあげるだけです。

Voltaを使用していない場合は、単純にNodeのPATHに置き換えていただければOKです。

3. precommitで走らせたい処理を追加する

huskyがインストールされているディレクトリに移動し、下記コマンドを実行するだけです。

npx husky add .husky/pre-commit "{コミット時に実行したいコマンド}"

今回の場合npx husky add .husky/pre-commit "npm run build"となります。

これを実行し正常に動くと、下記のどちらかの挙動になります。

  • pre-commitファイルがない場合 → ファイルが生成され、指定したコマンドが自動で記載される
  • pre-commitファイルがある場合 → ファイルが更新され、指定したコマンドが自動で追記されている

今後コミットを行う際は、pre-commitの中にあるコマンドが実行されてからコミットされます。

4. いざ動作確認

テストするパターンはふたつです。

npm run buildが通りコミットされるパターンと、通らずに弾かれるパターン。

これはソースをわざと崩したり、コメントで// コミットテストなどと追記してテストすればよいと思います。

どちらも試してみて正常に動いていれば、導入完了です。お疲れさまでした。

よくあるエラー

エラーとしてはおもに二種類かなと思います。

  • precommitが走った結果、エラー
  • precommitが実行できないエラー

前者は正常で、そもそもエラーを検知するためのものなのでこれで正解です。

ただ後者は検知するための処理が実行できていないので、おそらくPATHを通す部分が間違えています。

エラー内容としては下記のようなものがでます。

husky - pre-commit hook exited with code 1 (error)

zshを使っているけど.bash_profileにPATHを通しちゃったとか、あるいはPATHを間違えていたとか、

Nodeがそもそも入っていないとか、コミットするブランチやリポジトリそのものが違うとか、

ネットに繋がっていないとか、別の人のモニターを見ていたとか、

ファイルを保存していないとか(これがまじでよくある)。

そのあたりを疑ってみるとよいかもしれないです。

Windowsの場合

Windowsの場合はPATHを通す作業がいらないみたいです。

インストールしておわり。楽ですね。

さいごに

なんか『さいごに』って設けたほうがかっこいいかなと思って、見出しをつけました。

あんまりなに書いたらいいかわからないのでおわります。

ではよきprecommitライフを〜