跳到内容

ESLint 插件

Next.js 提供了一个 ESLint 插件 @next/eslint-plugin-next,它已捆绑在基本配置中,可以捕获 Next.js 应用程序中常见的问题。

设置 ESLint

使用 ESLint CLI (flat config) 快速进行 lint 检查

  1. 安装 ESLint 和 Next.js 配置

    终端
    pnpm add -D eslint eslint-config-next @eslint/eslintrc
  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,
      // Override default ignores of eslint-config-next.
      globalIgnores([
        // Default ignores of eslint-config-next:
        '.next/**',
        'out/**',
        'build/**',
        'next-env.d.ts',
      ]),
    ])
     
    export default eslintConfig
  3. 运行 ESLint

    终端
    pnpm exec eslint .

参考

eslint-config-next 中使用了以下 ESLint 插件的推荐规则集

规则

完整的规则集如下

在推荐配置中启用规则描述
@next/next/google-font-display使用 Google Fonts 强制执行字体显示行为。
@next/next/google-font-preconnect确保与 Google Fonts 一起使用 preconnect
@next/next/inline-script-id对于具有内联内容的 next/script 组件,强制使用 id 属性。
@next/next/next-script-for-ga使用 Google Analytics 的内联脚本时,优先使用 next/script 组件。
@next/next/no-assign-module-variable禁止对 module 变量赋值。
@next/next/no-async-client-component禁止客户端组件作为异步函数。
@next/next/no-before-interactive-script-outside-document禁止在 pages/_document.js 之外使用 next/scriptbeforeInteractive 策略。
@next/next/no-css-tags禁止手动 stylesheet 标签。
@next/next/no-document-import-in-page禁止在 pages/_document.js 之外导入 next/document
@next/next/no-duplicate-head禁止在 pages/_document.js 中重复使用 <Head>
@next/next/no-head-element禁止使用 <head> 元素。
@next/next/no-head-import-in-document禁止在 pages/_document.js 中使用 next/head
@next/next/no-html-link-for-pages禁止使用 <a> 元素导航到内部 Next.js 页面。
@next/next/no-img-element禁止使用 <img> 元素,因为它会导致 LCP 变慢和带宽占用更高。
@next/next/no-page-custom-font禁止页面专用自定义字体。
@next/next/no-script-component-in-head禁止在 next/head 组件中使用 next/script
@next/next/no-styled-jsx-in-document禁止在 pages/_document.js 中使用 styled-jsx
@next/next/no-sync-scripts禁止同步脚本。
@next/next/no-title-in-document-head禁止在 next/documentHead 组件中使用 <title>
@next/next/no-typos防止 Next.js 数据获取函数中常见的拼写错误
@next/next/no-unwanted-polyfillio防止来自 Polyfill.io 的重复 polyfills。

我们建议使用适当的集成,以便在开发过程中直接在代码编辑器中查看警告和错误。

移除 next lint

从 Next.js 16 开始,next lint 已被移除。

作为移除的一部分,Next 配置文件中的 eslint 选项不再需要,可以安全移除。

示例

在 monorepo 中指定根目录

如果您在 Next.js 未安装在根目录(例如 monorepo)的项目中使用 @next/eslint-plugin-next,您可以使用 eslint.config.mjs 中的 settings 属性告诉 @next/eslint-plugin-next 您的 Next.js 应用程序在哪里

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 可以是路径(相对或绝对)、glob(即 "packages/*/")或路径和/或 glob 的数组。

禁用规则

如果您想修改或禁用受支持插件(reactreact-hooksnext)提供的任何规则,您可以直接使用 eslint.config.mjs 中的 rules 属性进行更改

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',
    },
  },
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of 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,
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of eslint-config-next:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

如果 @next/eslint-plugin-next 中的一些规则会影响 Core Web Vitalsnext/core-web-vitals 会将其默认的警告规则更新为错误。

通过 Create Next App 构建的新应用程序会自动包含 next/core-web-vitals 入口点。

使用 TypeScript

除了 Next.js ESLint 规则之外,create-next-app --typescript 还会将 TypeScript 专用 lint 规则与 next/typescript 一起添加到您的配置中

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,
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of eslint-config-next:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

这些规则基于 plugin:@typescript-eslint/recommended。有关更多详细信息,请参阅 typescript-eslint > Configs

与 Prettier 结合使用

ESLint 还包含代码格式化规则,这可能会与您现有的 Prettier 设置冲突。我们建议在您的 ESLint 配置中包含 eslint-config-prettier,以使 ESLint 和 Prettier 协同工作。

首先,安装依赖项

终端
pnpm add -D eslint-config-prettier

然后,将 prettier 添加到您现有的 ESLint 配置中

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,
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of eslint-config-next:
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
  ]),
])
 
export default eslintConfig

对暂存文件运行 lint

如果您想将 ESLint 与 lint-staged 结合使用,在暂存的 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,除非满足以下条件。

如果满足以下条件:

  • 您已安装以下一个或多个插件(单独安装或通过其他配置(例如 airbnbreact-app)安装)
    • react
    • react-hooks
    • jsx-a11y
    • import
  • 您已定义了与 Next.js 中 Babel 配置不同的特定 parserOptions(不建议这样做,除非您已自定义 Babel 配置
  • 您已安装 eslint-plugin-import 并定义了 Node.js 和/或 TypeScript 解析器 来处理导入

那么我们建议,如果您更喜欢 eslint-config-next 中配置这些属性的方式,则删除这些设置,或者直接从 Next.js ESLint 插件扩展

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

该插件可以正常安装在您的项目中

终端
pnpm 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'],
  // List of ignore patterns.
  globalIgnores([]),
])
 
export default eslintConfig

next 配置已处理 parserpluginssettings 属性的默认值设置。除非您需要针对您的用例使用不同的配置,否则无需手动重新声明这些属性。

如果您包含任何其他可共享配置,则**您需要确保这些属性未被覆盖或修改**。否则,我们建议删除任何与 next 配置共享行为的配置,或者如上所述直接从 Next.js ESLint 插件扩展。

版本更改
v16.0.0next linteslint next.config.js 选项已移除,取而代之的是 ESLint CLI。可使用 codemod 帮助您进行迁移。