pre-commit hookをプロジェクトで共有したいしprettierもeslintもよしなにしてほしい

プロジェクトにESLintやRubocopのようなLinter, PrettierやRufoといったFormatterは導入していますか？
いいですよね、人間が細かいコーディングルールを気にすること無く神様にお任せでよしなにやってくれる。とても嬉しい。

とはいえですよ、これらの実行を手運用に任せてるとしばしば実行し忘れてしまい、
LinterやFormatterを実行しただけのコミットが生まれてしまいがちです。

そういうときにはpre-commit hookやpre-push hookなんていうありがたーい仕組みがあるわけですが
なんとこちら、.gitディレクトリ配下にあるのでプロジェクトで共有できません。ああもったいない！

ということでこれを解決するためのnpmパッケージがあります。
[typicode/husky](https://github.com/typicode/husky)

今回はこちらを中心に、prettierやeslintをよしなにしてみたり、
[okonet/lint\-staged](https://github.com/okonet/lint-staged) を導入してステージに入ってるファイルだけを対象にしてみたりします。

ちなみに実行するコマンドとしてrubocopやrufoを指定することでnpmパッケージではないものも普通にpre-commit hook書けることができるようです。やったね。
（JS関係ないプロジェクトでもpre-commit hookやpre-push hookを矯正するためだけにhuskyを導入する人もいるとか。）

なお、この記事では、eslintとprettierが喧嘩しないLintルールの設定についてはここでは省きます。

環境構築滅多にやらない勢なので、こうするともっとええんやでとかあったらどしどしコメントをお寄せください。

## husky を導入してpre-commit hook とpre-push hookを導入する
まずhuskyをプロジェクトに導入しましょう。

```
npm install --save-dev husky 
OR
yarn add -D husky
```

package.jsonに以下を追加します。

```package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}
```

これでcommitとpushの前に `"npm test"` コマンドが実行されるようになります。
複数のファイルを実行したいときは`sh hoge.sh`とか`node hoge.js`ファイルを作って実行すればいいです。

## pre-commit hookでeslintとprettierをコマンドライン実行する
eslintとprettierを併用するには`eslint`、`prettier`の他に
`eslint-plugin-prettier` も必要みたいです。

```
npm install --save-dev eslint prettier eslint-plugin-prettier
OR
yarn add -D eslint prettier eslint-plugin-prettier
```

前述の通り、eslintとprettierが喧嘩しないLintルールの設定についてはここでは省きます。
[ESLintとPrettierを併用するときの設定\(eslint\-plugin\-prettier, eslint\-config\-prettier\) \- dackdive's blog](https://dackdive.hateblo.jp/entry/2019/03/15/100000)
このあたりの記事とかが参考になるかもしれません。


さて、huskyでeslintとprettierを実行し、エラーがあったらコミットを失敗し、
自動整形結果をgit addするようにしたいところです。

でも、自動整形するのはgit addしてstagingしたコードに限定したいですよね？

[okonet/lint\-staged](https://github.com/okonet/lint-staged) こちらを使うことで、stagingしてるファイルだけを対象にできます。

ということでlint-stagedをインストールして使ってみましょう！

```
npm install --save-dev lint-staged
OR
yarn add -D lint-staged
```

package.jsonに下記の設定を追加します。
例では .jsファイルと.vueファイルに適用するようになってますが、jsxだったりtsだったり対象にしたいファイルはプロジェクトによって異なると思いますので適宜設定してください。

```package.json
  ...,
 "husky": {
     "hooks": {
       "pre-commit": "lint-staged"
     }
  },
  "lint-staged": {
    "*.{js,vue}": [
      "eslint --fix",
    ]
  },
  ...
```

これで、stagedなファイルだけを対象にprettierとeslintがかかり、git addしてくれるようになります。
やったね！

>@puku0x 2020-04-13 00:28
>v10以降のlint-stagedではgit addは不要になったようです。 

とのことなので、 `git add` の行を削除しました。 thx!

### 参考にしました
- [huskyでgit commit時にnpm testを走らせる \- code\-log](https://code-log.hatenablog.com/entry/2018/12/02/075600)
- [eslint prettier husky を使った簡単環境構築 \- Qiita](https://qiita.com/berry99/items/d1ca66b477f48856256d)
- [PrettierとLinterを併用する \- Qiita](https://qiita.com/sigwyg/items/ebb21ef70550cee7a163)
- [Node\.jsで正常終了するとき process\.exit\(0\) を呼んではいけない \- 銀の弾丸](https://takamints.hatenablog.jp/entry/dont-invoke-the-process-exit-on-success)
- [コミット前に Lint を強制するなら lint\-staged が便利 \- Qiita](https://qiita.com/ybiquitous/items/553479cfcb2cee124ae0)

### 余談
- [eslint\-plugin\-prettier と prettier\-eslintの使い分け \- Qiita](https://qiita.com/ayuareu/items/23d34605b2e9194651f0)

eslintとprettierを併用する方法として、prettier-eslintというものもあります