特定のディレクトリに変更があるときだけhusky(prettier)を走らせる
5分目次
プロダクトがモノレポ構成になった
.
├── README.md
├── backend/
├── docker-compose.yml
├── envoy/
├── frontend/
├── init
└── proto/
携わるプロダクトがフロントTS, バックRailsを切り分けていたのだが此度マイクロサービスからモノレポになった(なんかこの流れ最近よく見る気がする)。
特にこだわりはないのでそれ自体はいいのだが、問題点がいくつか出てきた。
- バックにしか差分がない時もフロント用のhusky(pre-commit)が走るようになった
- VSCode用設定ファイルのbackend, frontend間での共有
- gittree?というGUIでhuskyが干渉して壊れた
このうち、1と2を解消できたので手順を書く。3はGUIを使用してるのが1人だけだったのでCUIでgit操作してもらうことで事なき(?)を得てる。
バックにしか差分がない時もフロント用のhusky(pre-commit)が走るようになった
経緯
husky is 何 についてはほぼ割愛。commitする前に任意のコマンドを自動で実行できて、大抵の場合はcommitする前にprettier/eslintでファイルのフォーマット/エラー検知をするのに利用する、以上。
当然だけどモノレポになったことによってgit addしたファイルの中にfrontendがなくてもhuskyで設定したpre-commitのアクションが走るようになった。具体的にはprettierとESLintなのだが、プロダクトの規模が中〜大なので監視対象のファイルが200以上は優にあり、commitした時にそれらのファイルをずらっと検証していくのはバックエンドの人からしたら「なんでフロントいじってないのにフロントの検証のために待たなきゃいけないんだ」感あるのは想像に易いので修正する必要があった。
修正方法
シェルスクリプト書いたことないけどそれでないと対応できなそうなので頑張った。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd $(dirname "$0")/../
# git addした差分の一覧を変数に格納し、その中でfrontendの文字列を含むものを抜き出す
changedFiles=$(git diff --diff-filter=d --cached --name-only)
# 変更リストにfrontendが含まれている場合はlint-staged(pre-commit)実行
if [[ "$changedFiles" == *frontend/* ]]; then # 👈 `frontend/`の箇所はご自身の環境によって変更する必要あり
npm run pre-commit # 👈 ここはお好きなコマンドで。大抵の人は `yarn lint-staged`かも
else
# 含まれない場合はfrontendの変更なしというメッセージ出力
echo "[frontend/.husky/pre-commit] frontendの変更なし"
fi
huskyが走り始めたら差分のあるファイル一覧を取得し、その中に『frontend/』というパスが含まれていればnpm run pre-commit
を走らせている。ここは各自yarn lint-staged
にするなり環境に合わせて修正の必要あり。
一個注意点として当初はgrep -E 正規表現
できちんとフィルタリングしようと思ったが一部ケースでエラーが出たのでif文で制御することにした。backend/にfrontend/
という接頭辞のつくファイルはまずないだろうし、仮にあったとしてもバックエンドのcommitの時にprettierが走ってしまうだけでそこまでクリティカルでないので問題に直面してからの対応にすることにした。ただ、backend/frontend/hogeみたいなディ
ちなみにこれは確かhusky v7以上(latest)とかで動作確認済みで数年前のv5だったかとは色々勝手が違かった気がするのでそこはご留意ください。
VSCode用設定ファイルのbackend, frontend間での共有
経緯
次の問題点として、今までcode ~/frontend
という感じでフロントディレクトリを開いてたのだが、モノレポになってからは基本的にcode ~/mono
とかで開いて、ターミナル2個開いて、片方ではcd backend && rails s
、もう片方ではcd frontend && npm run dev
みたいな方法で使用する(「一つのウィンドウでフロント/バック見渡せる」にモノレポの恩恵の多くも詰まってる気がするので)。
ただし、そうなると今度は~/frontend/.vscode/settings.jsonは効かなくなってしまい、.vscodeディレクトリをルート直下に持ってくる必要が出てくる。つまり、フロントとバックで同じ.vscodeディレクトリを参照するという具合。
そうなるとフロント用の設定がバックに影響してしまう可能性がある。また逆も然り。
修正方法
ひとまずこれを暫定的な対処法とすることにした。
{
"files.associations": {
"*.ts": "typescript",
"*.tsx": "typescript"
},
"[typescript]": {
"editor.tabSize": 2,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
バックではrbファイルのみだしだしフロントではtsファイルのみなので、拡張子で適用するルールをラップする方法。
当面はこれでいいのかなって感じで他にいい方法見つけ次第そちらに移そうと思う。