モノレポでhusky, lint-stagedをセットアップ

フロントエンド

はじめに

husky, lint-stagedを導入するにあたってモノレポ構成への対応で詰まったので、手順を残しておきます。

今回はNext.jsにhusky, lint-stagedを導入する体ですが、lintコマンド以外はほぼ変わらないです。

僕はエディタの拡張機能で保存のたびにlinterが動作するように設定することをオススメしてます。
ただ、エディタは好みがあったり、初学者はうまく動作しないこともあったりします。
そういった事情があり、コードレビューで指摘するのが面倒になってきた方は是非参考にしてみてください。

ファイル構成

モノレポ感出すためにわざわざ階層が深くなるようにしてます。
プロジェクトディレクトリにDockerfileを含めたくない方とかはこんな感じになるんですかね。

root
├- .git
├- docker-compose.yml
├- api
└- nextjs_container
   ├- Dockerfile
   └- nextjs
      ├- src
      ├- package.json
      └- etc ... 

バージョン

husky@8.0.1
lint-staged@13.0.3

husky, lint-staged導入手順

コマンド類は全部root/nextjs_container/nextjsで実行してます。

インストール

npm install --save-dev husky lint-staged

husky準備用コマンド追加

.gitがある場所を基準にする必要があるので、モノレポの場合はcdしたり、パスを指定したりする必要があります。

{
  ...
  "scripts": {
    ...
    "prepare": "cd ../../ && husky install nextjs_container/nextjs/.husky"
  },
  ...
}

huskyディレクトリ作成

以下コマンドでroot/nextjs_container/nextjs/.huskyが作成されればOKです。
( どうやらbashでは動かないっぽい?ので注意してください。issue )

npm run prepare

lint-stagedコマンド設定

以下コマンドでroot/nextjs_container/nextjs/.husky/pre-commitが作成されればOKです。
pre-commitの部分はpre-pushなど他のhooksに適宜変更できます。

npx husky add .husky/pre-commit "npx lint-staged"

生成されたroot/nextjs_container/nextjs/.husky/pre-commitを以下のように変更します。
.gitが起点になるので、cdしてます。

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

// 下1行追記
cd ./nextjs_container/nextjs
npx lint-staged

root/nextjs_container/nextjs/.lintstagedrc.jsを以下の内容で新規に作成します。
Next.jsじゃない方はlintterの部分は適宜書き換えてください。

module.exports = {
  "**/*.{js,jsx,ts,tsx}": [
    filenames =>
      `next lint --fix --file ${filenames
        .map(file => file.split(process.cwd())[1])
        .join(" --file ")}`,
    "prettier --write",
  ],
  "**/*.{scss,css,sass}": ["stylelint --fix '**/*.{css,scss}'"],
};

こんな感じで対象ファイルと実行したいコマンドの配列を登録すればOKです。
next lintには変更されたファイルのパスを渡しています。
prettierstylelintの部分は上手くいかなかったので割愛してます。。

実行

コミットした際に以下のように表示されればOKです。

✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
✨  Done in 6.00s.

タイトルとURLをコピーしました