
はじめに
コミット前にlint系のチェックをしたいケースってあると思います。特にチーム開発とかの場合、全員がlintをちゃんと実行してほしいとかあるかと。そういったときのためにコミットのタイミングでlint系のコマンドを実行するための仕組みとしてhuskyとlint-stagedを組み合わせたものが定番かと思います。
新しいプロジェクトのリポジトリを作るたびにこの組み合わせのセットアップを行うのですが、毎回ググりながらやるのでいい加減に面倒になって自分用のメモを残しておきます。
huskyとlint-stagedそのものについては大雑把に説明すると、huskyがコミット前に何らかの処理を実行するためのツール、lint-stagedがGitでステージにあるファイルに対してlintを実行するためのツールです。
インストール
yarn add husky lint-staged -D
lint-staged の設定
実行したいコマンドをpackage.jsonに以下のように追加。内容は自身の環境にあわせて適宜変更。
"lint-staged": { "*.{js,ts,tsx}": "eslint --cache --fix", "*.{js,ts,tsx,md,json}": "prettier --write" },
フックの設定
Gitのフックでhuskyが使えるようにしていく。具体的には.huskyディレクトリを作成したり、package.jsonのprepareに記述を追加したり。
yarn husky install
このコマンドで.huskyディレクトリができあがりGitのフックが有効化される。
あとはこのコマンドをリポジトリをクローンしたりした場合にも実行されるようにpackage.jsonのprepareにも追加しておく。具体的にはpackage.jsonのscripts内に以下のように追加する。なお、このサンプルはNest.jsのアプリを作った際のものなので余計なものがいろいろ含まれているが、大事なのは最下行の一行だけだ。
"scripts": { "prebuild": "rimraf dist", "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", "prepare": "husky install", },
.huskyの中身はこんな感じになっている。

ここにフックで実際に実行するものを用意していく。
pre-commitフックの作成
今回はコミット前にlintなどを実行するのが目的なのでpre-commitフックを作成する。Gitのフック自体はそれ以外にもpre-pushフックなどいろいろとある。
.huskyにpre-commitフックとして実行するシェルスクリプトをpre-commitというファイル名で用意する。中身は以下のようなものだ。
#!/bin/sh . "$(dirname "$0")/_/husky.sh" yarn lint-staged
ちなみにこれは以下のコマンドを実行することで生成することもできる。
yarn husky add .husky/pre-commit "yarn lint-staged"
これだけで完了。
まとめ
これで晴れてコミットする前にlintを実行することができるようになった。今回はpre-commitでlint-stagedを実行しただけですが、実際にはpre-commitのファイル内にyarn testとかも記述しておくとコミット前にテスト実行することなんかもできます。
ちなみにコミット前にlintの実行をしていくのが目的ではあるものの一応抜け道もあります。