ESlint入門(Next.js)
はじめに
今までもESlintを使用していましたがきちんと理解していませんでした。
ver9.0.0にて大きな変更があったこともあり勉強と忘備録のために本記事を作成しました。
とても分かりやすく記事をまとめてくださっている方がいたので、その内容をインプットするためにまとめた記事となっています。
ESlintとは
ESlintとはJavaSctiptやTypeScriptの静的解析ツールです。
設定ファイルに設けたルールに則り、違反している場合は警告やエラーを通知するでけでなく、自動修正することもできます。
これによりコードの品質を向上させ、コードの可読性を高め、保守しやすくすることができます。
さらにチーム内でコーディングスタイルを統一することができます。
Eslintはコード成形ツールのPrettierやテストフレームワークのJest・Vitest、Git操作、ビルドツールと連携することができるのも特色です。
バージョンについて
2024年3月にver.9.0.0がリリースされ、ルールの設定形式がフラット形式にデフォルト化されました。本記事ではフラット設定形式に対応しています。
プロジェクト作成
今回はcreate-next-appを使用します。
{
"name": "zenn-eslint",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "15.3.2"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"eslint": "^9",
"eslint-config-next": "15.3.2",
"@eslint/eslintrc": "^3"
}
}
フラット設定形式
プロジェクト内にはeslint.config.mjsというファイルが作成されています。
従来はeslintrcという設定ファイルを使用していましたがver.9より変更となっています。
現在の状態
eslint.config.mjsの状態を見てみます。
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
export default eslintConfig;
eslintConfigにはあらかじめNext.jsが推奨する2つのルールセットが適用されています。
- next/core-web-vitals:Web パフォーマンス指標に関するルール
- next/typescript:TypeScript のコード品質向上のためのルール
ESLintの動作確認
2つのルールを追加します。
-
@typescript-eslint/consistent-type-imports
一貫性のあるインポートをサポートするためのルール
自動修正をテストするために追加 -
no-console
consoleの消し忘れがないか確認するためのルール
警告も含めて厳格にチェックするために追加
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
files: ["**/*.{js,mjs,cjs,ts,tsx}"],
rules: {
"@typescript-eslint/consistent-type-imports": [
"error",
{ prefer: "type-imports" },
],
"no-console": "warn",
},
},
];
動作確認のためpage.tsxを変更します。
import { FC } from "react";
const Page: FC = () => {
console.log("hello world");
return (
<main>
<div className="flex justify-center items-center h-screen">
<div className="flex flex-col items-center">
<h1 className="text-2xl font-bold">Hello World</h1>
</div>
</div>
</main>
);
};
export default Page;
typeを省略しているimport文にエラーが出ています。
consoleがあるため警告がでています。
問題を確認してみます。
npm run lint
自動修正してみます。
npm run -- --fix
エラーがでていたimport文に自動でtypeが追記され、エラーが解消されています。
クリーンアップします。
git reset --hard HEAD; git clean -fd
ESLint対象外ファイルを指定
npm run lintではなくnpx eslintを実行してみます。
npx eslint
するとターミナルに大量のエラーがはかれます。
これは、.nextディレクトリやnode_modulesディレクトリにあるファイルに対しても実行されているためです。
これらには適用されてほしくないので実行対象外のファイルを指定します。
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
ignores: ["**/.next/**", "**/node_modules/**"],
},
];
もう一度実行してみます。
npx eslint
先ほどでていたエラーが出なくなりました。
ESLintスクリプトのカスタマイズ
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint"
+ "lint": "next lint && npx eslint . --ext .js,.jsx,.ts,.tsx,.mjs",
+ "lint:fix": "next lint --fix && npx eslint . --ext .js,.jsx,.ts,.tsx,.mjs --fix"
},
- npm run lint - 通常のlintチェック
- npm run lint:fix - 修正可能な問題を修正
Next.js固有のESLintの設定
next.config.tsのESLint設定について解説します。
現在の状態を見てみます。
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;
ignoreDuringBuilds
ビルド時のESLintの動作を制御します。
trueにするとビルド時にESLintのエラーがあってもビルドすることができます。
開発初期はfalse、開発が進んだ段階でfalseにすることで厳格なチェックを行えます。
デフォルトはtrueです。
dirs
特定のディレクトリのみをESLintの対象にすることができます。
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
eslint: {
dirs: ["src/pages", "src/components"],
},
};
export default nextConfig;
Prettierの導入
Prettierとパッケージをインストールします。
- prettier : Prettier本体
- prettier-plugin-tailwindcss : TailwindCSSをフォーマットするプラグイン
npm i -D prettier prettier-plugin-tailwindcss
Prettier設定ファイルを作成します。
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
const config = {
plugins: ["prettier-plugin-tailwindcss"],
};
export default config;
スクリプトを追加します。
{
"scripts": {
+ "format": "prettier --check \"**/*.{ts,tsx,js,jsx,cjs,mjs,md,json,lintstagedrc,yml,yaml}\" --cache",
+ "format:fix": "prettier --write \"**/*.{ts,tsx,js,jsx,cjs,mjs,md,json,lintstagedrc,yml,yaml}\" --cache",
},
}
npm run format : コードフォーマットが必要なファイルの警告として列挙されます。
npm run format:fix : 自動でフォーマットされます。
GitHooksの導入
GitHooksを導入し、ステージングされたファイルに自動的にESLintを実行するための設定をします。
Huskyとlint-stagedを使用します。
GitHooksとは
Gitリポジトリで特定のイベントが発生した場合に自動で実行されるスクリプトです。
Huskyとは
Gitフックを用いてステージングされたファイルにテストを行うことができるツールです。
lint-stagedとは
Gitでステージングされたファイルに対してLinterを実行することができるツールです。
パッケージをインストールします。
npm i -D husky lint-staged
npx husky init
コマンドの実行順を制御できるようにするために.husky/pre-commitファイルを編集します。
- npm test
+ npx lint-staged --concurrent false --allow-empty
Huskyの設定ファイルを作成します。
{
"*.{js,jsx,ts,tsx,mjs}": ["eslint --fix"],
"**/*.{ts,tsx,js,jsx,cjs,mjs,md,json,lintstagedrc,yml,yaml}": [
"prettier --write"
]
}
正常に動作するか確認するためファイルを編集します。
import { FC } from "react";
const Page: FC = () => {
return (
<main>
<div className="flex h-screen items-center justify-center">
<div className="flex flex-col items-center">
<h1 className="text-2xl font-bold">Hello World</h1>
</div>
</div>
</main>
);
};
export default Page;
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
files: ["**/*.{js,mjs,cjs,ts,tsx}"],
rules: {
"@typescript-eslint/consistent-type-imports": [
"error",
{ prefer: "type-imports" },
],
},
},
];
export default eslintConfig;
git addします。
git add .
ステージングされているpage.tsxを見てみると自動修正されていることがわかります。
commitしてpage.tsxを見てみます。
git commit -m "ESLint の設定を追加"
GitHub Acrtionsの導入
GitHub Actionsの設定ファイルとカスタムアクションを作成します。
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: "20.9.0"
NPM_VERSION: "10.9.2"
jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup environment
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
npm-version: ${{ env.NPM_VERSION }}
lint:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
npm-version: ${{ env.NPM_VERSION }}
- run: npm run lint
format:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
npm-version: ${{ env.NPM_VERSION }}
- run: npm run format
typecheck:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
npm-version: ${{ env.NPM_VERSION }}
- run: npm run typecheck
name: "Setup and install"
description: "Common setup steps for Actions"
inputs:
node-version:
description: "Node.js version"
required: true
npm-version:
description: "NPM version"
required: true
runs:
using: composite
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: "npm"
- name: Install dependencies
shell: bash
run: npm install --frozen-lockfile
コミット、マージします。
git add . && git commit -m "Next.js プロジェクトに GitHub Actions を導入" &&
git checkout main &&
git merge feature
githubのActions>Jobs>lintを見てみます。
npm run lintが実行されていることがわかります。
まとめ
ver.9からデフォルト化されたflat設定形式とGitフックとCI/CDにおけるESLintの設定方法について学びました。冒頭に挙げたZennの記事が大変わかりやすく、勉強になりました。次はCI/CDについて学びたいと思います。
Discussion