ESLint Plugin
Next.js 提供了一个 ESLint 插件,@next/eslint-plugin-next,已捆绑在基础配置中,可以捕获 Next.js 应用程序中的常见问题。
设置 ESLint
使用 ESLint CLI(flat config)快速启用代码检查:
-
安装 ESLint 和 Next.js 配置:
pnpm add -D eslint eslint-config-nextnpm i -D eslint eslint-config-nextyarn add --dev eslint eslint-config-nextbun add -d eslint eslint-config-next -
使用 Next.js 配置创建
eslint.config.mjs:eslint.config.mjsimport { 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 -
运行 ESLint:
pnpm exec eslint .npx eslint .yarn eslint .bunx eslint .
参考
eslint-config-next 中使用了以下 ESLint 插件的推荐规则集:
规则
完整的规则集如下:
| 在推荐配置中启用 | 规则 | 描述 |
|---|---|---|
| @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 | 防止 Client Components 成为异步函数。 | |
| @next/next/no-before-interactive-script-outside-document | 防止在 pages/_document.js 之外使用 next/script 的 beforeInteractive 策略。 | |
| @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/document 的 Head 组件中使用 <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 应用程序:
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 eslintConfigrootDir 可以是路径(相对或绝对)、glob(即 "packages/*/")或路径和/或 glob 的数组。
禁用规则
如果你想修改或禁用受支持插件(react、react-hooks、next)提供的任何规则,可以在 eslint.config.mjs 中使用 rules 属性直接更改它们:
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 规则集来启用它。
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 eslintConfignext/core-web-vitals 更新 @next/eslint-plugin-next,将默认情况下为警告的若干规则在影响 Core Web Vitals 时设置为错误。
对于使用 Create Next App 构建的新应用程序,
next/core-web-vitals入口点会自动包含。
使用 TypeScript
除了 Next.js ESLint 规则外,create-next-app --typescript 还会将 TypeScript 特定的 lint 规则与 next/typescript 一起添加到你的配置中:
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 配置中包含 eslint-config-prettier,以使 ESLint 和 Prettier 协同工作。
首先,安装依赖:
pnpm add -D eslint-config-prettiernpm i -D eslint-config-prettieryarn add --dev eslint-config-prettierbun add -d eslint-config-prettier然后,将 prettier 添加到你现有的 ESLint 配置中:
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
如果你想将 ESLint 与 lint-staged 一起使用,以便对暂存的 git 文件运行 linter,请将以下内容添加到项目根目录的 .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,除非满足一些条件。
推荐的插件规则集
如果满足以下条件:
- 你已经安装了以下一个或多个插件(单独安装或通过其他配置(如
airbnb或react-app)安装):reactreact-hooksjsx-a11yimport
- 你定义了与 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',
],
}该插件可以正常安装在你的项目中:
pnpm add -D @next/eslint-plugin-nextnpm i -D @next/eslint-plugin-nextyarn add --dev @next/eslint-plugin-nextbun add -d @next/eslint-plugin-next这消除了由于跨多个配置导入相同插件或解析器而可能发生的冲突或错误的风险。
其他配置
如果你已经使用单独的 ESLint 配置并希望包含 eslint-config-next,请确保它在其他配置之后最后扩展。例如:
import { defineConfig, globalIgnores } from 'eslint/config'
import nextPlugin from '@next/eslint-plugin-next'
const eslintConfig = defineConfig([
nextPlugin.configs['core-web-vitals'],
// 忽略模式列表。
globalIgnores([]),
])
export default eslintConfignext 配置已经处理了为 parser、plugins 和 settings 属性设置默认值。除非你的用例需要不同的配置,否则无需手动重新声明这些属性。
如果你包含任何其他可共享配置,你需要确保这些属性不会被覆盖或修改。否则,我们建议删除与 next 配置共享行为的任何配置,或如上所述直接从 Next.js ESLint 插件扩展。
| 版本 | 变更 |
|---|---|
v16.0.0 | 移除了 next lint 和 eslint next.config.js 选项,改用 ESLint CLI。可以使用 codemod 来帮助你迁移。 |