TypeScript/JavaScript

Huskyをv6に上げたらcommitできずに動かない

ハローワールド。

この前弊blogのライブラリ群をとにかく$ yarn upgrade --latestでアップデートしたところ、諸々動かなくなりまして。
基本的にはwebpack5関連で、なんとか動いたとcommitをしようとしたところ、エラーが発生してcommitできませんでした。

error Command "husky-run" not found.

gitのcommit時にはgit hooksを利用してlintやtestなどを行うのが常かと思います。私のblogもhuskyを利用してyarn lintを走らせています。そのhuskyがどうやらエラーしている模様。

調べてみるとhuskyはv4からv6にかけて大幅なアップデートがあったようです。公式でもv4からv6のマイグレーションガイドがあるので、それで事足りるかと思いますが、当記事でも触れてみたいと思います。

アップデート方法

package.jsonhuskyrc.jsonに皆さんのhuskyの設定があると思います。
私の場合は下記のような感じでした。

package.json
"lint-staged": { "*.{js,vue}": "yarn lint" }, "husky": { "hooks": { "pre-commit": "lint-staged" } },

v6に変更する場合はまず.husky/ディレクトリを作成します。
そして、キーをファイル名としたシェルスクリプトを作成します。今回はpre-commitという名前のシェルスクリプトを下記のように作成しました。

.husky/pre-commit
#!/bin/sh . "$(dirname "$0")/_/husky.sh" yarn lint

そしてGithookを有効にするために下記コマンドを実行します。

$ npx husky install # または $ yarn husky install

自動的にGithookを有効にするためにpackage.jsonを編集します。ただし、yarn v2は対応していないため、yarn v2についてのガイドを別途参照してください。

package.json
"scripts": { ... "prepare": "husky install", ... }

$ yarn husky installをすることで、.git/confighooksPath = .huskyと設定が入るため、.huskyフォルダに入れたhooksが適用されます。それによりgit hooksが上手く動くというわけです。

何故

ぱっと見ると、v4のほうが設定自体は簡単なような気がしますし、.huskyというフォルダができてしまいます。

その辺りに関してはWhy husky has dropped conventional JS configにすべて記載があります。

以前のhuskyではgit hooksというhooksすべてを作成して、下記のシェルスクリプトを実行していました。

. "$(dirname "$0")/husky.sh"

実際に、例えば.git/hooks/pre-commitなどを見てもらえば上記の定義となっているかと思います。

そこでhusky.shを読んでみると、今度は最終的にyarn run husky-run $hookName($hookNameは例えばpre-commitなど)を実行しているような動きでした。しかしながら、これでは実行するものがなくてもすべてのhookが動いていまいます。何も動かないならまだしも、必ずyarn run husky-runを動かすわけですね。

そしてgit 2.9がやってきました。

You can now specify a custom path for hooks

yarn husky installではこのhooksのカスタムパス機能を利用して.huskyフォルダをhooksのパスとして登録します。
今まで.git/hooksという亜空間で定義していたものが.huskyというフォルダに移ってきました。こうすることで無駄なくgit hooksを定義できます。

.huskyってフォルダ名が嫌だ、とか「じゃあhusky要らなくない?」とかいった疑問もWhy husky has dropped conventional JS config - butに記載があるので気になった方は読んでみてください。