😈

Next.jsでcommit時にESLintとPrettierを実行する

2023/11/15に公開

はじめに

個人用のホームページに 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に、下記を追加してインストールしたプラグインを有効化する。

.eslintrc.json
{
  "extends": ["plugin:@typescript-eslint/recommended", "next/core-web-vitals"]
}

package.jsonscripts を追加する

package.json
 "scripts": {
  "lint": "next lint",
  "lint:fix": "next lint --fix",
  },

Prettier の導入

Prettier をインストールする。

npm install prettier

※Tailwind CSS のクラス名を並び替えるプラグインを入れる場合

npm install prettier-plugin-tailwindcss

.prettierrcに prettier のルールとプラグインの設定を行う。
(ルールの詳細はこちら)

.prettierrc
{
  "tabWidth": 2,
  "printWidth": 90,
  "trailingComma": "es5",
  "semi": true,
  "singleQuote": true,
  "plugins": ["prettier-plugin-tailwindcss"]
}

Prettier と ESlint で競合するルールをオフにする

npm install eslint-config-prettier

.eslintrc.json の設定を追加する。

.eslintrc.json
{
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "next/core-web-vitals",
    "prettier"
  ]
}

package.json にscriptsを追加する

package.json
 "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 を実行する事ができる。

package.json
"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.jslint-stagedの設定を記述する。(公式ドキュメント)
ルートディレクトリに.lintstagedrc.jsを作成

.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.jsonscriptsに実行したい処理(npm run check-types)を記述する。

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

npm run check-types

package.jsonscriptsを追加する。

package.json
 "scripts": {
    "check-types": "tsc --noEmit",
  },

スクリプトに実行権限を与えれば終了 👏

chmod a+x .husky/pre-push
chmod a+x .husky/pre-commit
GitHubで編集を提案

Discussion