Menu

ESLint

Next.jsは@next/eslint-plugin-nextというESLintプラグインを提供しており、基本設定にすでにバンドルされているため、Next.jsアプリケーション内の一般的な問題を検出することが可能です。

ESLintのセットアップ

ESLint CLI(フラット設定)を使用して、すばやくLintを実行できます:

  1. ESLintとNext.js設定をインストールします:

    pnpm add -D eslint eslint-config-next
    npm i -D eslint eslint-config-next
    yarn add --dev eslint eslint-config-next
    bun add -d eslint eslint-config-next
  2. Next.js設定を使用してeslint.config.mjsを作成します:

    eslint.config.mjs
    import { defineConfig, globalIgnores } from 'eslint/config'
    import nextVitals from 'eslint-config-next/core-web-vitals'
     
    const eslintConfig = defineConfig([
      ...nextVitals,
      // eslint-config-nextのデフォルト無視設定をオーバーライドします。
      globalIgnores([
        // eslint-config-nextのデフォルト無視設定:
        '.next/**',
        'out/**',
        'build/**',
        'next-env.d.ts',
      ]),
    ])
     
    export default eslintConfig
  3. ESLintを実行します:

    pnpm exec eslint .
    npx eslint .
    yarn eslint .
    bunx eslint .

リファレンス

以下のESLintプラグインの推奨ルールセットはすべてeslint-config-next内で使用されています:

ルール

ルールの完全なセットは以下の通りです:

推奨設定で有効化ルール説明
@next/next/google-font-displayGoogle Fontsを使用する際のfont-displayの動作を実装します。
@next/next/google-font-preconnectGoogle Fontsでpreconnectが使用されていることを確認します。
@next/next/inline-script-idインラインコンテンツを含むnext/scriptコンポーネントにid属性を実装します。
@next/next/next-script-for-gaGoogle Analytics用のインラインスクリプトを使用する場合は、next/scriptコンポーネントを優先します。
@next/next/no-assign-module-variablemodule変数への代入を防止します。
@next/next/no-async-client-componentClient Componentが非同期関数になることを防止します。
@next/next/no-before-interactive-script-outside-documentpages/_document.jsの外部でnext/scriptbeforeInteractive戦略の使用を防止します。
@next/next/no-css-tags手動のスタイルシートタグを防止します。
@next/next/no-document-import-in-pagepages/_document.jsの外部でのnext/documentのインポートを防止します。
@next/next/no-duplicate-headpages/_document.jsでの<Head>の重複使用を防止します。
@next/next/no-head-element<head>要素の使用を防止します。
@next/next/no-head-import-in-documentpages/_document.jsでのnext/headの使用を防止します。
@next/next/no-html-link-for-pagesNext.jsの内部ページに移動するための<a>要素の使用を防止します。
@next/next/no-img-elementLCPが遅くなり、帯域幅が増加するため、<img>要素の使用を防止します。
@next/next/no-page-custom-fontページ専用のカスタムフォントを防止します。
@next/next/no-script-component-in-headnext/headコンポーネント内でのnext/scriptの使用を防止します。
@next/next/no-styled-jsx-in-documentpages/_document.jsでのstyled-jsxの使用を防止します。
@next/next/no-sync-scripts同期スクリプトを防止します。
@next/next/no-title-in-document-headnext/documentからHeadコンポーネントを使用した<title>の使用を防止します。
@next/next/no-typosNext.jsのデータ取得関数における一般的なタイプミスを防止します。
@next/next/no-unwanted-polyfillioPolyfill.ioからの重複ポリフィルを防止します。

開発中に、コードエディタで警告とエラーを直接表示するために、適切な統合を使用することをお勧めします。

next lintの削除

Next.js 16以降、next lintは削除されました。

削除の一部として、Next.設定ファイルのeslintオプションは不要になり、安全に削除できます。

モノレポ内のルートディレクトリを指定する

Next.jsがルートディレクトリにインストールされていないプロジェクト(モノレポなど)で@next/eslint-plugin-nextを使用している場合、eslint.config.mjssettingsプロパティを使用して、Next.jsアプリケーションの場所を@next/eslint-plugin-nextに伝えることができます:

eslint.config.mjs
import { defineConfig } from 'eslint/config'
import eslintNextPlugin from '@next/eslint-plugin-next'
 
const eslintConfig = defineConfig([
  {
    plugins: {
      next: eslintNextPlugin,
    },
    settings: {
      next: {
        rootDir: 'packages/my-app/',
      },
    },
    files: [
      // ...files
    ],
    ignores: [
      // ...ignores
    ],
  },
])
 
export default eslintConfig

rootDirは、パス(相対パスまたは絶対パス)、グロブ(例:"packages/*/")、またはパスやグロブの配列を指定できます。

ルールの無効化

サポートされているプラグイン(reactreact-hooksnext)で提供されるルールを変更または無効化する場合は、eslint.config.mjsrulesプロパティを使用して直接変更できます:

eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
 
const eslintConfig = defineConfig([
  ...nextVitals,
  {
    rules: {
      'react/no-unescaped-entities': 'off',
      '@next/next/no-page-custom-font': 'off',
    },
  },
  // eslint-config-nextのデフォルト無視設定をオーバーライドします。
  globalIgnores([
    // eslint-config-nextのデフォルト無視設定:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

Core Web Vitalsを使用する

ESLint設定でnext/core-web-vitalsルールセットを拡張して有効にします。

eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
 
const eslintConfig = defineConfig([
  ...nextVitals,
  // eslint-config-nextのデフォルト無視設定をオーバーライドします。
  globalIgnores([
    // eslint-config-nextのデフォルト無視設定:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

next/core-web-vitalsは、@next/eslint-plugin-nextを更新して、Core Web Vitalsに影響を与える多数のルールについて、デフォルトでは警告であるものをエラーに変更します。

next/core-web-vitalsエントリポイントは、Create Next Appで構築された新しいアプリケーションに自動的に含まれます。

TypeScriptを使用する

Next.js ESLintルールに加えて、create-next-app --typescriptは、設定にnext/typescriptを使用したTypeScript固有のLintルールも追加します:

eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
import nextTs from 'eslint-config-next/typescript'
 
const eslintConfig = defineConfig([
  ...nextVitals,
  ...nextTs,
  // eslint-config-nextのデフォルト無視設定をオーバーライドします。
  globalIgnores([
    // eslint-config-nextのデフォルト無視設定:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

これらのルールはplugin:@typescript-eslint/recommendedに基づいています。詳細については、typescript-eslint > Configsを参照してください。

Prettierを使用する

ESLintには、既存のPrettierセットアップと競合する可能性のあるコードフォーマットルールも含まれています。ESLintとPrettierが連携するようにするために、ESLint設定にeslint-config-prettierを含めることをお勧めします。

まず、依存関係をインストールします:

pnpm add -D eslint-config-prettier
npm i -D eslint-config-prettier
yarn add --dev eslint-config-prettier
bun add -d eslint-config-prettier

その後、既存のESLint設定にprettierを追加します:

eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
import prettier from 'eslint-config-prettier/flat'
 
const eslintConfig = defineConfig([
  ...nextVitals,
  prettier,
  // eslint-config-nextのデフォルト無視設定をオーバーライドします。
  globalIgnores([
    // eslint-config-nextのデフォルト無視設定:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

ステージングファイルでLintを実行する

lint-stagedでESLintを使用して、ステージングされたgitファイルでLinterを実行する場合は、プロジェクトのルートにある.lintstagedrc.jsファイルに以下を追加します:

.lintstagedrc.js
const path = require('path')
 
const buildEslintCommand = (filenames) =>
  `eslint --fix ${filenames
    .map((f) => `"${path.relative(process.cwd(), f)}"`)
    .join(' ')}`
 
module.exports = {
  '*.{js,jsx,ts,tsx}': [buildEslintCommand],
}

既存の設定の移行

アプリケーションにすでにESLintが設定されている場合は、いくつかの条件が満たされていない限り、eslint-config-nextを含める代わりに、このプラグインから直接拡張することをお勧めします。

推奨プラグインルールセット

以下の条件が当てはまる場合:

  • 次のプラグインの1つ以上がすでにインストールされている(別途またはairbnbやreact-appなどの別の設定を通じて):
    • react
    • react-hooks
    • jsx-a11y
    • import
  • Next.js内でBabelがどのように設定されているかとは異なる特定のparserOptionsを定義している(Babel設定をカスタマイズしていない限りお勧めしません)
  • Node.jsまたはTypeScriptリゾルバーeslint-plugin-importがインストールされており、インポートを処理するように定義されている

その場合は、eslint-config-next内でこれらのプロパティがどのように設定されているかの方法を好む場合は、これらの設定を削除するか、代わりにNext.js ESLintプラグインから直接拡張することをお勧めします:

module.exports = {
  extends: [
    //...
    'plugin:@next/next/recommended',
  ],
}

プラグインはプロジェクトで通常どおりインストールできます:

pnpm add -D @next/eslint-plugin-next
npm i -D @next/eslint-plugin-next
yarn add --dev @next/eslint-plugin-next
bun add -d @next/eslint-plugin-next

これにより、複数の設定にわたって同じプラグインまたはパーサーをインポートすることにより発生する可能性のある競合またはエラーのリスクが軽減されます。

追加設定

すでに別のESLint設定を使用していて、eslint-config-nextを含めたい場合は、他の設定の後に最後に拡張されることを確認してください。例えば:

eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextPlugin from '@next/eslint-plugin-next'
 
const eslintConfig = defineConfig([
  nextPlugin.configs['core-web-vitals'],
  // 無視パターンのリスト。
  globalIgnores([]),
])
 
export default eslintConfig

next設定は、parserpluginssettingsプロパティのデフォルト値の設定をすでに処理しています。ユースケースに異なる設定が必要な場合を除き、これらのプロパティを手動で再度宣言する必要はありません。

他の共有可能な設定を含める場合、これらのプロパティが上書きされたり変更されたりしないようにする必要があります。そうでなければ、next設定と動作を共有する設定を削除するか、上記で説明したように直接Next.js ESLintプラグインから拡張することをお勧めします。

バージョン変更
v16.0.0next lintとnext.config.jsのeslintオプションはESLint CLIの優先で削除されました。移行を支援するためのcodemodが利用可能です。