はじめに
よくメンターの人から「コードフォーマット効いていない!!」と言われていました。
毎回「ごめんなさい ごめんなさい」と思いながら再度pushする日々でした。
自動でGitにPushする際にフォーマッターが動けばいいと思い調べてみたら、huskyとlint-stagedで自動整形を行うようにできるらしい。
今回は、huskyとlint-stagedの実装の仕方やつまずいたところを紹介します!
そもそもhuskyとlint-stagedとは?
huskyとはnpm パッケージの1つで、commitやpushなどのGitの操作を行う際に自動でコマンドを実行できるもの。
lint-stagedとは、変更したファイルに対してフォーマットをかけることができるもの。
今回は、フォーマッターを実行しコードの整形を行ってからGitにPushを行うようにしました。
導入方法
※ huskyやpre-commitのバージョンによってはNode.jsのバージョンをアップデートする必要がある
yarnの導入方法を記述する
1. Prettierのインストール
Prettierとは自動でコードを成形してくれるツール
$ yarn add --dev --exact prettier
2. ESLintのインストール (任意)
ESLintとはコードルールを検証するツール
$ yarn add eslint
$ yarn add --dev eslint-config-prettier eslint-plugin-import
eslint-config-prettier
: ESLintフォーマットルールを無効化し、バグを検出するルールのみを有効にするプラグイン
eslint-plugin-import
: importの順番を定義するプラグイン
3. huskyとlist-stagedのインストール
$ yarn add husky lint-staged
4. huskyのセットアップ
以下のコマンドを実行することで、.husky
ディレクトリとその中に.husky.sh
というファイルが作成される。
$ yarn husky
※ huskyのバージョンv9以前の場合
$ yarn husky install
5. hooksを作成
pre-commitの設定ファイルを追加
$ echo "npx lint-staged" > .husky/pre-commit
6. package.jsonに以下のようなものを記述
sacriptsに記述:yarnを実行した際に".hosky/_"というGitHooksの設定を作成するため。
※husky V9以前の場合はhusky install
と記述
lint-staged
の要素を追加: ファイルの拡張子を指定してeslint,prettierを実行している
"scripts": {
~~省略~~
#"prepare": "husky" # ← yarn2以降を使用している場合は使えない
"postinstall": "husky"# ← yarn2以降でscriptsを書きたい場合はこちらを用いる
},
~~省略~~
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
lint-stagedの説明
-
eslint --fix
:Eslintのルールに従ってコードを整形し、エラーを解消するスクリプト -
prettier --write
:フォーマッターを行いコードを上書きするスクリプト
複数プロジェクト(monorepo環境)の場合
※ .git
を参照するためrootディレクトリにhuskyをダウンロードする
自分はmonorepo環境での実装でつまずいた。
構成
├─package.json
├── /frontend
│ ├── ...
│ └── package.json
└── /backend
├── ...
└── package.json
1. 個々のプロジェクトに移動する
$ cd frontend もしくは backend
2. Prettierのインストール(プロジェクト内で)
$ yarn add --dev --exact prettier
3. ESLintのインストール(プロジェクト内で) 任意
$ yarn add eslint
$ yarn add --dev eslint-config-prettier eslint-plugin-import
4. huskyのインストール(プロジェクト内で)
$ yarn add husky lint-staged
5. package.jsonに以下のようなものを記述(プロジェクト内で)
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
1~5までの操作をfrontend,backendどちらでも行う
6. rootディレクトリにhusky設定ファイルを作成
$ yarn husky
※husky V9以前の場合はyarn husky install
と記述
$ yarn husky install
7. package.json
にhuskyの設定を記述 (rootディレクトリー)
"scripts": {
~~~~~
"postinstall": "husky"
}
8. hooksの作成
$ echo "npx lint-staged" > .husky/pre-commit
monorepo環境で実装する際につまずいたこと
huskyの初期設定をどこに記述するか
- rootディレクトリに記述する場合 → 今回採用
- 問題なく機能するが、rootのpackage.jsonに記述したくない
- 各プロジェクトのpackage.jsonに記述する場合
- hooksPathの問題により、最終的にはどちらか一方のプロジェクトの設定しか適用されない 参考
2番ができない理由、hooksPathの制約
- core.hooksPathには1つのパスしか指定できないため、最終的にどちらか一方のworkspaceのパスしか記載されない
- hooksPathに指定された.husky/_の設定しか動作しない
Lefthookを用いることで上記の問題を解決することができる
- 個々のプロジェクト毎にhookするファイルを制限できる
- 設定ファイルがローカル、グローバルどこにあっても参照可能
- 並列実行が可能
- Node.js以外のプロジェクトも管理可能
- Lefthookは、lefthookバイナリがシステムのどこかにインストールされていれば認識される
まとめ
huskとlint-stagedをモノレポ環境で使うとなると少し制限があり使いずらいので、Lefthookで実装することをお勧めする。
これで、自信を持って「お願いします!!」という感じにレビューをお願いすることができる。
今回の記事のモノレポ問題は、メンターと一緒に討論をしここまで調べた。これを一人でできるようになりたいそう日々頑張っている自分である。
参考URL
モノレポ構成で husky 設定方法
コードを綺麗に保ちたい?それhuskyでできるよ!
husky公式
lefthook公式
Lefthook: 多機能Gitフックマネージャ
Git Hooks を複数実行したかった