Menu

ESLint

Next.js 提供了开箱即用的集成 ESLint 体验。在 package.json 中添加 next lint 作为一个脚本:

package.json
{
  "scripts": {
    "lint": "next lint"
  }
}

然后运行 npm run lintyarn lint

Terminal
yarn lint

如果你的应用程序中还没有配置 ESLint,你将会被引导完成安装和配置过程。

Terminal
yarn lint

你会看到这样的提示:

? 你想如何配置 ESLint?

❯ 严格 (推荐)
基础
取消

可以选择以下三个选项之一:

  • 严格:包括 Next.js 的基本 ESLint 配置以及更严格的 核心 Web 指标规则集。这是首次设置 ESLint 的开发者的推荐配置。

    .eslintrc.json
    {
      "extends": "next/core-web-vitals"
    }
  • 基础:包括 Next.js 的基本 ESLint 配置。

    .eslintrc.json
    {
      "extends": "next"
    }
  • 取消:不包含任何 ESLint 配置。只有在你计划设置自己的自定义 ESLint 配置时才选择此选项。

如果选择了两个配置选项中的任何一个,Next.js 将自动在你的应用程序中安装 eslinteslint-config-next 作为依赖项,并在项目根目录创建一个包含所选配置的 .eslintrc.json 文件。

现在,你可以在每次想要运行 ESLint 检查错误时运行 next lint。一旦设置了 ESLint,它也会在每次构建 (next build) 期间自动运行。错误会导致构建失败,而警告则不会。

如果你不希望 ESLint 在 next build 期间运行,请参考 忽略 ESLint 的文档。

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

ESLint 配置

默认配置 (eslint-config-next) 包含了你在 Next.js 中获得最佳开箱即用 linting 体验所需的一切。如果你的应用程序中还没有配置 ESLint,我们建议使用 next lint 来设置 ESLint 并使用此配置。

如果你想将 eslint-config-next 与其他 ESLint 配置一起使用,请参考 附加配置 部分,了解如何在不引起任何冲突的情况下进行操作。

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

这将优先于 next.config.js 中的配置。

ESLint 插件

Next.js 提供了一个 ESLint 插件 eslint-plugin-next,它已经捆绑在基础配置中,使得可以捕获 Next.js 应用程序中的常见问题。完整的规则集如下:

在推荐配置中启用

规则描述
@next/next/google-font-display强制使用 Google Fonts 时的 font-display 行为。
@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防止手动添加样式表标签。
@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。

如果你已经在应用程序中配置了 ESLint,我们建议直接扩展这个插件,而不是包含 eslint-config-next,除非满足一些条件。请参考 推荐插件规则集 以了解更多信息。

自定义设置

rootDir

如果你在一个 Next.js 未安装在根目录的项目中使用 eslint-plugin-next (比如 monorepo),你可以在 .eslintrc 中使用 settings 属性告诉 eslint-plugin-next 在哪里找到你的 Next.js 应用程序:

.eslintrc.json
{
  "extends": "next",
  "settings": {
    "next": {
      "rootDir": "packages/my-app/"
    }
  }
}

rootDir 可以是一个路径 (相对或绝对),一个 glob (例如 "packages/*/"), 或者一个路径和/或 glob 的数组。

自定义目录和文件的 Linting

默认情况下,Next.js 会对 pages/app/components/lib/src/ 目录中的所有文件运行 ESLint。然而,你可以在 next.config.jseslint 配置中使用 dirs 选项来指定在生产构建时要检查的目录:

next.config.js
module.exports = {
  eslint: {
    dirs: ["pages", "utils"], // 在生产构建 (next build) 期间只对 'pages' 和 'utils' 目录运行 ESLint
  },
};

同样,--dir--file 标志可以用于 next lint 来检查特定的目录和文件:

Terminal
next lint --dir pages --dir utils --file bar.js

缓存

为了提高性能,ESLint 处理的文件信息默认会被缓存。这些信息存储在 .next/cache 或你定义的 构建目录 中。如果你包含了任何依赖于单个源文件内容以外的 ESLint 规则并需要禁用缓存,请在运行 next lint 时使用 --no-cache 标志。

Terminal
next lint --no-cache

禁用规则

如果你想修改或禁用由支持的插件 (reactreact-hooksnext) 提供的任何规则,你可以直接在 .eslintrc 中使用 rules 属性进行更改:

.eslintrc.json
{
  "extends": "next",
  "rules": {
    "react/no-unescaped-entities": "off",
    "@next/next/no-page-custom-font": "off"
  }
}

核心 Web 指标

当首次运行 next lint 并选择 严格 选项时,next/core-web-vitals 规则集会被启用。

.eslintrc.json
{
  "extends": "next/core-web-vitals"
}

next/core-web-vitals 更新了 eslint-plugin-next,将一些默认为警告的规则升级为错误,如果这些规则影响了 核心 Web 指标

对于使用 Create Next App 构建的新应用程序,next/core-web-vitals 入口点会被自动包含。

TypeScript

除了 Next.js 的 ESLint 规则外,create-next-app --typescript 还会通过 next/typescript 为你的配置添加 TypeScript 特定的 lint 规则:

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

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

与其他工具一起使用

Prettier

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

首先,安装依赖:

Terminal
npm install --save-dev eslint-config-prettier
 
yarn add --dev eslint-config-prettier
 
pnpm add --save-dev eslint-config-prettier
 
bun add --dev eslint-config-prettier

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

.eslintrc.json
{
  "extends": ["next", "prettier"]
}

lint-staged

如果你想将 next lintlint-staged 一起使用,以在暂存的 git 文件上运行 linter,你需要在项目根目录的 .lintstagedrc.js 文件中添加以下内容,以指定使用 --file 标志。

.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],
};

迁移现有配置

推荐插件规则集

如果你的应用程序中已经配置了 ESLint,并且满足以下任何条件:

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

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

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

可以正常在你的项目中安装插件,而无需运行 next lint

Terminal
npm install --save-dev @next/eslint-plugin-next
 
yarn add --dev @next/eslint-plugin-next
 
pnpm add --save-dev @next/eslint-plugin-next
 
bun add --dev @next/eslint-plugin-next

这样可以消除由于在多个配置中导入相同的插件或解析器而可能发生的冲突或错误的风险。

附加配置

如果你已经使用了单独的 ESLint 配置,并且想要包含 eslint-config-next,请确保它在其他配置之后被扩展。例如:

.eslintrc.json
{
  "extends": ["eslint:recommended", "next"]
}

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

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