[2025年 Next.js v15]ESLint(v9 Flat Config) + Prettierによる開発環境の構築
Next.js(v15)での、ESLint(v9)・Prettierによる開発環境の構築についてまとめます。ESLintはv9で、Flat Config Filesという設定方法に変わったので、これに対応しています。
定番的な必要最低限の設定をしているので、これをベースにカスタマイズしていただければと思います。
初心者の方は、とりあえずこの手順通りに設定すればOKです。
バージョン(2025年1月最新)
- Nodejs: 22.13.0
- Next.js: 15.1.5
- ESLint: 9
- Pretteir: 3.4.2
- VSCode: 1.96.4
Nextjsのインストール
以下のコマンドで、Next.jsをインストールします。
対話で、TypeScript、ESLint、Tailwind CSS、App Routerを全てYesにします。
npx create-next-app@latest
Prettierのインストールと設定
Prettierは、文末セミコロンの有無やインデント幅のようなコードの見た目を整形(フォーマット)するものです。
コードフォーマッターと呼ばれるもので、コードの処理内容とは無関係です。
Prettierをインストールします。
npm install -D prettier
Tailwind CSSに対応するため、以下をインストールします。
npm install -D prettier-plugin-tailwindcss
prettier.config.mjs(設定ファイル)を作成します。
export default config = {
plugins: ['prettier-plugin-tailwindcss'],
semi: true,
singleQuote: true,
trailingComma: 'all',
tabWidth: 2,
printWidth: 100,
endOfLine: 'lf',
};
ESLintの設定
ESLintは、コードを解析し、品質に関わる問題を検知・修正するものです。
静的解析ツールと呼ばれるもので、Prettierと違い、コードの処理内容に関わります。
TypeScriptに対応するため、以下をインストールします。
npm install -D @eslint/js typescript-eslint
PrettierとESLintの競合を防止するため、以下をインストールします。
npm install -D eslint-config-prettier
ESLint上でPrettierを動かす場合は、eslint-plugin-prettierも必要になりますが、これはPrettier公式で既に非推奨になっています。
ここでは、PrettierとESLintは独立させる方針で構築します。
VSCodeの拡張機能で、ファイル保存時に自動的にフォーマットするよう設定するため、わざわざESLintに乗せる必要もないかと。
Tailwind CSSに対応するため、以下をインストールします。
npm install -D eslint-plugin-tailwindcss
あと、importの順序を整列し、使用されていないimportを削除すると、コードの見通しが良くなるため、以下をインストールします。
npm install -D eslint-plugin-import
npm install -D eslint-plugin-unused-imports
Next.jsインストール時に、eslint.config.mjs(設定ファイル)が作成されているので、これを編集します。
(従来の.eslintrc.jsonによる設定は、v10から廃止となるようです。)
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { FlatCompat } from '@eslint/eslintrc';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import tailwind from 'eslint-plugin-tailwindcss';
import importPlugin from 'eslint-plugin-import';
import unusedImports from 'eslint-plugin-unused-imports';
import eslintConfigPrettier from 'eslint-config-prettier';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
export default tseslint.config(
{
files: ['*.ts', '*.tsx'], // 読み込むファイル
},
{
ignores: ['**/.next/**/*'], // 無視するファイル
},
eslint.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
...compat.extends('next/core-web-vitals'),
...tailwind.configs['flat/recommended'],
{
// @typescript-eslintに関する設定
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
},
rules: {
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-misused-promises': 'off',
},
},
{
// tailwindcssに関する設定
settings: {
tailwindcss: {
whitelist: ['hidden-scrollbar', '-webkit-scrollbar'],
},
},
},
{
// eslint-plugin-importに関する設定
plugins: {
import: importPlugin,
},
rules: {
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal'],
alphabetize: { order: 'asc', caseInsensitive: true },
'newlines-between': 'always', // import groups 1行空ける
pathGroups: [
{ pattern: 'src/components/**', group: 'internal', position: 'before' },
{ pattern: 'src/lib/**', group: 'internal', position: 'before' },
],
},
],
'import/newline-after-import': 'error',
'import/no-duplicates': 'error',
},
},
{
// eslint-plugin-unused-importsに関する設定
plugins: {
'unused-imports': unusedImports,
},
rules: {
'unused-imports/no-unused-imports': 'error',
},
},
{
// その他設定
files: ["src/**/*.{js,jsx,ts,tsx}"],
linterOptions: {
reportUnusedDisableDirectives: "error",
},
languageOptions: {
globals: {
React: "readonly",
},
},
rules: {
"react/jsx-boolean-value": "error", // JSXの中でのbooleanの使用
"react/jsx-curly-brace-presence": "error", // JSXの中での余分な{}の使用
},
},
eslintConfigPrettier, // Prettierとの競合防止
);
デフォルトで読み込んでいるnext/core-web-vitalsは、内部的にeslint-config-nextを読み込んでいます。
eslint-config-next内で、next/recommended、react/recommended、react-hooks/recommendedを読み込んでいるため、これらのインストールは不要です。
コマンドの設定
コマンドでフォーマットやリントができるよう、package.jsonの"script"に、formatとlintを追加します。
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start -p 3000",
"format": "npx prettier --write src",
"lint": "next lint --dir src"
},
VSCodeの設定
ESLint、Prettier、Tailwind CSSの拡張機能をインストールします。
ESLint:画面にErrorやWarningの下線を表示
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
Prettier:保存時に自動フォーマット
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
Tailwind CSS IntelliSense:保存時のclassの並び替え、class補間等
https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
.vscode/setting.json(設定ファイル)を作成します。
拡張機能やFlat Configを有効にするよう設定します。
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.options": {
"overrideConfigFile": "eslint.config.mjs"
},
"editor.quickSuggestions": {
"strings": true
}
}
Warningの注意点
注意点が一つあります。
eslint.config.mjsで*.config.mjsをignoreしないと、これらのファイルにエラーの赤線が上部に表示されます。
ただ、これをignoreすると、今度はnpm run lintやnpm run build で「The Next.js plugin was not detected in your ESLint configuration.」というWariningが出力されます。
リントやビルド自体は最後まで通るのですが、Warningが出ると何かモヤモヤするので、自分はignoreせず赤線の方を妥協しています。
まとめ
Next.js(v15)での、ESLint(v9)・Prettierによる開発環境の構築についてまとめました。
ESLintは、v9でFlat Config Filesによる設定方法がデフォルトとなり、v10で従来の.eslintrc.jsonは廃止となるようです。
これからNext.jsを使い始める方は、まずはこの記事の設定を行い、それをベースにカスタマイズしていくといいでしょう。