Next.jsでcommit時にESLintとPrettierを実行する
はじめに
個人用のホームページに Husky を使用して、コミット時に ESLint と Prettier が実行されるようにしたので備忘録として残す。
環境
- Next.js 13.5.2(App Router)
- TypeScript 5.1.6
- Tailwind CSS 3.3.3
- ESLint 8.47.0
- Prettier 3.0.2
ESLint の導入
最初の Next.js インストール時に「Would you like to use ESLint with this project?」で ”Yes” と答えているので ESLint は自動的にインストールされている。
ただ、TypeScript 用の ESLint が含まれていないので下記のコマンドでインストールする。
npm install @typescript-eslint/eslint-plugin
ルートディレクトリの.eslintrc.json
に、下記を追加してインストールしたプラグインを有効化する。
{
"extends": ["plugin:@typescript-eslint/recommended", "next/core-web-vitals"]
}
package.json
に scripts
を追加する
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
},
Prettier の導入
Prettier をインストールする。
npm install prettier
※Tailwind CSS のクラス名を並び替えるプラグインを入れる場合
npm install prettier-plugin-tailwindcss
.prettierrc
に prettier のルールとプラグインの設定を行う。
(ルールの詳細はこちら)
{
"tabWidth": 2,
"printWidth": 90,
"trailingComma": "es5",
"semi": true,
"singleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
}
Prettier と ESlint で競合するルールをオフにする
npm install eslint-config-prettier
.eslintrc.json
の設定を追加する。
{
"extends": [
"plugin:@typescript-eslint/recommended",
"next/core-web-vitals",
"prettier"
]
}
package.json にscripts
を追加する
"scripts": {
"format": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,ts,tsx,json,css}' --plugin=prettier-plugin-tailwindcss"
},
Husky と lint-staged の導入
husky はpre-commit
(コミット前)やpre-push
(プッシュ前)にpackage.json
に記述したスクリプトを実行する。
lint-staged は、Git でステージング(add)されたファイルに対してのみ ESLint や Prettier のコマンドを実行することを目的としたもの。
コミット前に実行させる
npm install husky lint-staged
次のコマンドを実行して、設定の雛形が記述された.husky
ディレクトリを生成する。
npm husky install
他の開発者がclone後にnpm installしたとき、自動でnpm husky install
を実行させるようにする。
pnpm pkg set scripts.prepare="husky install"
package.json
にコマンドを設定する。
このコマンドが実行されることによって、ステージ上のファイルに対して ESLint や Prettier を実行する事ができる。
"devDependencies": {
// 省略
},
"lint-staged": {
"*.{ts,tsx}": [
"npm run lint",
"npm run format",
"npm run lint:fix"
]
}
pre-commit
(コミット前)をトリガーに、先ほど設定したlint-staged
コマンドを実行するために、.husky/pre-commit
に設定を記述する。
ルートディレクトリに次のファイルを生成する。
touch .husky/pre-commit
.husky/pre-commit
ファイルに実行したい処理(npm run lint-staged
)を記述
##!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint-staged
次に、.lintstagedrc.js
でlint-staged
の設定を記述する。(公式ドキュメント)
ルートディレクトリに.lintstagedrc.js
を作成
const path = require('path');
const buildEslintCommand = (filenames) =>
`next lint --fix --file ${filenames
.map((f) => path.relative(process.cwd(), f))
.join(' --file ')}`;
module.exports = {
'*.{js,jsx,ts,tsx}': [buildEslintCommand, 'prettier --write'],
};
これで、commit 前にステージングされたファイルに対して ESLint と Prettier を実行することができます。
追加で、プッシュ前に型チェックを実行させたいので
同じようにルートディレクトリに.husky/pre-push
を作成して設定を記述する。
touch .husky/pre-push
.husky/pre-push
ファイルとpackage.json
のscripts
に実行したい処理(npm run check-types
)を記述する。
##!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run check-types
package.json
にscripts
を追加する。
"scripts": {
"check-types": "tsc --noEmit",
},
スクリプトに実行権限を与えれば終了 👏
chmod a+x .husky/pre-push
chmod a+x .husky/pre-commit
Discussion