---
title: "新的 Nuxt ESLint 集成"
description: "我们改进了我们的 ESLint 集成，以支持 ESLint v9 以及新的平面配置，还有一个新的模块，具有更多功能。"
canonical_url: "https://nuxt.zhcndoc.com/blog/eslint-module"
---
# 新的 Nuxt ESLint 集成

> 我们改进了我们的 ESLint 集成，以支持 ESLint v9 以及新的平面配置，还有一个新的模块，具有更多功能。

## TL;DR

我们改进了我们的 ESLint 集成，以支持带有新平面配置的 ESLint v9。在此过程中，我们探索了许多新的可能性，使其更加个性化、强大，并提供更好的开发者体验。

你可以运行以下命令来安装新的 [`@nuxt/eslint`](https://eslint.nuxt.com/packages/module) 模块：

```bash [Terminal]
npx nuxi module add eslint
```

继续阅读故事或通过 [文档](https://eslint.nuxt.com/packages/module) 了解更多。

## 背景

[ESLint](https://eslint.org/) 已成为当今 web 开发的基本工具。它帮助你捕捉错误并强制执行项目中一致的编码风格。在 Nuxt，我们尽力为 ESLint 提供即开即用的经验，使其易于使用、配置，并遵循我们推荐的的最佳实践。

因为，Nuxt 和 ESLint 都发展了很多。历史上，我们最终得到了 [Nuxt 中 ESLint 的几种不同的包和集成](https://eslint.nuxt.com/guide/faq#package-disambiguation)，并且通常不清楚应该使用哪一个以及用于什么目的。我们收到了社区的很多反馈。

为了改善情况并使其面向未来，我们最近刷新了我们的 ESLint 集成，以支持 [ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/) 以及 [平面配置](https://eslint.org/docs/latest/use/configure/configuration-files)。它为自定义你的 ESLint 设置打开了许多更多的功能，提供了更直接和统一的体验。

## Nuxt ESLint 单仓库

我们将分散在不同仓库中的 ESLint 相关包移动到了一个单一的单仓库：[`nuxt/eslint`](https://github.com/nuxt/eslint)， 并配备了一个专门的新文档站点：[eslint.nuxt.com](https://eslint.nuxt.com/)。

为了帮助理解每个包之间的区别以及应该使用什么，我们还有一个 [FAQ](https://eslint.nuxt.com/guide/faq) 页面，比较它们并解释它们的作用域。

这个单仓库现在包括：

- `@nuxt/eslint` - Nuxt 3 的新一体化 ESLint 模块，支持项目感知的 ESLint 平面配置等。
- `@nuxt/eslint-config` - 适用于 Nuxt 3 的无偏见但可定制的共享 ESLint 配置。支持 [平面配置格式](https://eslint.org/docs/latest/use/configure/configuration-files) 和 [传统格式](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated)。
- `@nuxt/eslint-plugin` - 为 Nuxt 3 提供的 ESLint 插件提供 Nuxt 特定规则和配置。
- 两个 Nuxt 2 的维护模式包。

## ESLint 平面配置

在深入研究新的 Nuxt 集成之前，让我向你介绍 [ESLint 平面配置](https://eslint.org/docs/latest/use/configure/configuration-files) 的概念。

平面配置是在 ESLint `v8.21.0` 中作为实验性引入的配置格式，并在 [ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/) 中成为默认格式。

快速参考以区分：

- **平面配置**: `eslint.config.js` `eslint.config.mjs` 等。
- **传统配置**: `.eslintrc` `.eslintrc.json` `.eslintrc.js` 等。

### 为什么是平面配置？

[ESLint 的这篇博客文章](https://eslint.org/blog/2022/08/new-config-system-part-1/) 详细解释了平面配置系统背后的动机。简而言之，传统的 `eslintrc` 格式是在 JavaScript 早期设计的，当时 ES 模块和现代 JavaScript 特性尚未标准化。涉及许多隐含的惯例，并且 `extends` 特性使得最终配置结果难以理解和预测。这也使得共享配置难以维护和调试。

```jsonc [.eslintrc]
{
  "extends": [
    // 从 `import("@nuxtjs/eslint-config").then(mod => mod.default)` 解决
    "@nuxtjs",
    // 从 `import("eslint-config-vue").then(mod => mod.default.configs["vue3-recommended"])` 解决
    "plugin:vue/vue3-recommended",
  ],
  "rules": {
    // ...
  }
}
```

新的平面配置将插件和配置解析从 ESLint 的内部约定转移到了原生 ES 模块解析。这反过来使其更加显式和透明，允许你甚至可以从其他模块导入它。由于平面配置只是一个 JavaScript 模块，它也为更多的定制打开了大门。

## Nuxt 为平面配置预设

在最新的 [`@nuxt/eslint-config` 包](https://eslint.nuxt.com/packages/config#flat-config-format) 中，我们利用我们拥有的灵活性，提供了一个工厂函数，允许你以更高级的方式轻松自定义配置预设。以下是一个示例，展示如何使用它：

```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt()
```

`@nuxt/eslint-config` 从无偏见的基础配置开始，这意味着我们只包括 TypeScript、Vue 和 Nuxt 的最佳实践规则，并将代码风格、格式化等其余内容留给你来决定。你还可以运行 [Prettier](https://prettier.io/) 同时进行格式化，默认情况下使用默认值。

配置还允许你根据需要选择更多的有偏见的特性。例如，如果你想让 ESLint 也负责格式化，你可以通过将 `features.stylistic` 传递给工厂函数来启用它（由 [ESLint Stylistic](https://eslint.style/) 提供支持）：

```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: true
  }
})
```

或者使用选项对象调整你的偏好（[在这里了解更多选项](https://eslint.style/guide/config-presets#configuration-factory)）：

```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: {
      semi: false,
      indent: 2, // 4 或 'tab'
      quotes: 'single',
      // ...以及更多
    }
  }
})
```

如果你正在 [编写 Nuxt 模块](https://nuxt.com/docs/guide/going-further/modules)，你可以启用 `features.tooling` 以启用 Nuxt 模块开发规则：

```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    tooling: true
  }
})
```

...等等。平面配置中的工厂函数允许预设覆盖底层 ESLint 配置的复杂性，并为用户提供高级和用户友好的抽象，以便定制。所有这些都不会要求用户担心内部细节。

虽然这种方法为你提供了一个像 Prettier 一样的体验，配置最少（因为它由 ESLint 提供），但你仍然可以完全灵活地根据需要定制和覆盖细粒度规则和插件。

我们还制作了一个 [`FlatConfigComposer`](https://github.com/antfu/eslint-flat-config-utils#composer) 工具，来自 [`eslint-flat-config-utils`](https://github.com/antfu/eslint-flat-config-utils)，使其更容易覆盖和扩展平面配置。`@nuxt/eslint-config/flat` 中的工厂函数返回一个 `FlatConfigComposer` 实例：

```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  // ...Nuxt 集成的选项
})
  .append(
    // ...追加其他平面配置项
  )
  .prepend(
    // ...在基础配置之前预置其他平面配置项
  )
  // 根据其名称覆盖特定配置项
  .override(
    'nuxt/typescript', // 指定目标配置的名称，或索引
    {
      rules: {
        // ...覆盖规则
        '@typescript-eslint/no-unsafe-assignment': 'off'
      }
    }
  )
  // 等等，操作是可链的
```

通过这种方法，我们得到了两个世界中最好的东西：易于使用的简单性和高级抽象，以及定制和微调的力量。

## Nuxt ESLint 模块

更进一步，我们为 Nuxt 3 制作了新的一体化 [`@nuxt/eslint` 模块](https://eslint.nuxt.com/packages/module)。它利用 Nuxt 的上下文为你的项目生成项目感知和类型安全的 ESLint 配置。

### 项目感知规则

我们知道 Vue 的风格指南建议使用[多词名称用于组件](https://vue.zhcndoc.com/style-guide/rules-essential.html#use-multi-word-component-names) 以避免与现有和未来的 HTML 元素冲突。因此，在 [`eslint-plugin-vue`](https://github.com/vuejs/eslint-plugin-vue) 中，我们默认启用了规则 [`vue/multi-word-component-names`](https://eslint.vuejs.org/rules/multi-word-component-names.html)。这是一个好习惯，但我们知道在 Nuxt 项目中，并非所有 `.vue` 文件都注册为组件。像 `app.vue`、`pages/index.vue`、`layouts/default.vue` 等文件在其他 Vue 文件中不可用作组件，并且该规则对它们来说是不相关的。

通常，我们可以像这样为这些文件关闭规则：

```js [eslint.config.js]
export default [
  {
    files: ['*.vue'],
    rules: {
      'vue/multi-word-component-names': 'error'
    }
  },
  {
    files: ['app.vue', 'error.vue', 'pages/**/*.vue', 'layouts/**/*.vue'],
    rules: {
      // 对这些文件禁用规则
      'vue/multi-word-component-names': 'off'
    }
  }
]
```

它应该适用于大多数情况。然而，我们知道在 Nuxt 中你可以 [为每个目录自定义路径](https://nuxt.com/docs/api/nuxt-config#dir)，并且 [层](https://nuxt.com/docs/getting-started/layers) 允许你为每个目录有多个来源。这意味着 linter 规则将不够准确，并可能需要用户手动保持它们一致。

类似地，我们希望 [`vue/no-multiple-template-root`](https://eslint.vuejs.org/rules/no-multiple-template-root.html) 仅对 `pages` 和 `layouts` 等启用。随着案例的增加，要求用户手动维护规则变得不切实际。

这就是 `@nuxt/eslint` 的魔力所在！它利用 Nuxt 的上下文为你的项目结构生成特定的配置和规则。非常类似于 Nuxt 提供的 [`.nuxt/tsconfig.json`](http://nuxt.com/docs/guide/concepts/typescript#auto-generated-types)，你现在也有了项目感知的 `.nuxt/eslint.config.mjs` 可以扩展。

要使用它，你可以将模块添加到你的 Nuxt 项目中：

```bash [Terminal]
npx nuxi module add eslint
```

### 配置检查器 DevTools 集成

在迁移和研究新的平面配置过程中，我想出了一个想法，为平面配置制作一个交互式 UI 检查器，使配置更加透明和易于理解。当你安装了 `@nuxt/eslint` 模块时，我们已经将其集成到 [Nuxt DevTools](https://github.com/nuxt/devtools) 中，所以你可以在需要时轻松访问它。

![在 Nuxt DevTools 中作为标签页运行的 ESLint 配置检查器的截图](https://nuxt.zhcndoc.com/assets/blog/nuxt-eslint-inspector.png)

检查器允许你查看最终解析的配置、已启用的规则和插件，并进行快速匹配，看看规则和配置如何应用于特定文件。这对于调试和学习 ESLint 在你的项目中的工作方式非常有用。

我们很高兴 ESLint 团队也发现它很有用，并对将其用于更广泛的 ESLint 社区感兴趣。我们后来加入了这项工作，并将其制作成了 [官方 ESLint 配置检查器](https://github.com/eslint/config-inspector)（顺便说一下，它是用 Nuxt 构建的）。你可以阅读 [这篇公告文章](https://eslint.org/blog/2024/04/eslint-config-inspector/) 了解更多细节。

### 规则类型生成

配置 ESLint 的一个主要痛点是规则和配置的类型信息泄露。很难知道特定规则有哪些选项可用，并且需要你为每个规则跳转到文档来弄清楚。

再次感谢新的平面配置具有如此多的可能性。我们发现了一个新工具 [`eslint-typegen`](https://github.com/antfu/eslint-typegen)，我们可以为每个规则从规则配置模式生成相应的类型 **基于你实际使用的插件**。这意味着它是一个通用解决方案，适用于任何 ESLint 插件，并且类型始终准确且最新。

在 `@nuxt/eslint` 模块中，这个特性是开箱即用的，所以你将立即获得这种惊人的体验：

![展示 VS Code 中 ESLint 规则配置的类型检查和自动完成的截图](https://nuxt.zhcndoc.com/assets/blog/nuxt-eslint-typegen.png)

### Dev Server 检查器

有了新模块，我们抓住机会将 [`@nuxtjs/eslint-module`](https://github.com/nuxt-modules/eslint) 和 ESLint 的 dev server 检查器合并到新的 `@nuxt/eslint` 模块中，作为一个可选特性。

<note>

大多数时候你可能不需要这个特性，因为你的编辑器集成应该已经在你的编辑器中提供了 ESLint 诊断。然而，对于一些使用不同编辑器并且希望确保 ESLint 始终运行的团队来说，在某些情况下，在 dev server 中运行 ESLint 可能会有所帮助。

</note>

要启用它，你可以在模块选项中将 `checker` 选项设置为 `true`：

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: [
    '@nuxt/eslint'
  ],
  eslint: {
    checker: true // <---
  }
})
```

每当你遇到一些 ESLint 错误时，你将在控制台和浏览器中看到一个警告。要了解更多关于这个特性的信息，你可以查看 [文档](https://eslint.nuxt.com/packages/module#dev-server-checker)。

### 模块钩子

由于我们现在在 Nuxt 模块中具有代码生成能力和项目感知配置，我们实际上可以用这个做更多有趣的事情。一个是我们可以允许模块也贡献到 ESLint 配置中。想象一下，在未来，当你安装一个 Nuxt 模块如 `@nuxtjs/i18n` 时，它可以自动为 i18n 相关文件启用特定的 ESLint 规则，或者当你安装像 `@pinia/nuxt` 这样的东西时，它可以安装 Pinia ESLint 插件以强制执行 Pinia 的最佳实践，等等。

作为一个实验，我们制作了一个模块 [`nuxt-eslint-auto-explicit-import`](https://github.com/antfu/nuxt-eslint-auto-explicit-import)，它可以自动插入你的 Nuxt 项目中注册的自动导入的预配置 ESLint 预设。这样你就可以在使用 API 时获得与自动导入相同的出色开发体验，但在你的代码库中仍然有自动插入的显式导入。

这仍然处于早期阶段，我们仍在探索可能性和最佳实践。但我们对潜力和它所开辟的机会感到非常兴奋。我们将与社区合作，看看如何充分利用它。如果你有任何想法或反馈，请随时与我们分享！

## 生态系统

在 Nuxt，我们一直非常关心生态系统和社区。在我们采用新的平面配置和改善开发者体验的探索过程中，我们制作了很多工具来实现这一目标。它们都是通用的，并且可以在 Nuxt 之外使用：

- [`@eslint/config-inspector`](https://github.com/eslint/config-inspector)  - 官方 ESLint 配置检查器，为你的配置提供交互式 UI。
- [`eslint-typegen`](https://github.com/antfu/eslint-typegen)  - 根据你实际使用的插件为 ESLint 规则生成 TypeScript 类型。
- [`eslint-flat-config-utils`](https://github.com/antfu/eslint-flat-config-utils)  - 用于管理和组合 ESLint 平面配置的实用工具。

我们致力于支持更广泛的社区并与开发者合作，改进这些工具并扩大它们的可能性。我们很高兴看到这些工具如何使 ESLint 生态系统受益，并为整体开发者体验做出贡献。

## 未来

<tip>

平面配置格式仍然相当新，ESLint v9 只是在几周前发布的。插件和社区正在逐步赶上新格式。它仍处于探索和实验阶段。

</tip>

展望未来，我们渴望看到 ESLint 生态系统将如何继续发展，以及我们如何利用新功能和可能性进一步增强 Nuxt 的开发者体验。我们致力于为 Nuxt 用户提供无缝且强大的开发环境，我们将继续探索新思路并与社区合作以实现这一目标。


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
