ESLint v10.0.0 发布

我们刚刚发布了 ESLint v10.0.0,这是 ESLint 的一个重大版本升级。此版本添加了一些新功能并修复了先前版本中发现的几个错误。此版本还包含一些破坏性更改,请仔细阅读以下内容。

亮点

ESLint v10.0.0 是一个主要版本,包含几个新功能和破坏性更改。以下是一些最值得注意的更新。

安装

由于这是一个主要版本,npm 可能不会自动升级您。为了确保您使用的是此版本,请运行

npm i eslint@10.0.0 --save-dev

Node.js < v20.19.0, v21.x, v23.x 不再支持

截至本文发布时,Node.js v24.x 是 LTS 版本,因此我们停止支持所有早于 v20.19.0 的 Node.js 版本以及 v21.x 和 v23.x。

迁移指南

由于有很多更改,我们创建了一个 迁移指南,详细描述了破坏性更改以及您应该采取的步骤来解决这些更改。我们预计大多数用户应该能够在不进行任何构建更改的情况下升级,但如果您遇到问题,迁移指南应该是一个有用的资源。

新的配置文件查找算法

ESLint v10.0.0 通过 从每个被 lint 文件的目录开始 查找 eslint.config.*,而不是像 ESLint v9.x 那样从当前工作目录查找。新的行为允许在同一次运行中使用多个配置文件,并且在 monorepo 设置中特别有用。

在 ESLint v9.x 中,可以使用 v10_config_lookup_from_file 功能标志启用此配置查找行为。在 ESLint v10.0.0 中,此行为现在是默认行为,并且 v10_config_lookup_from_file 标志已被删除。

移除 eslintrc 功能

Flat config 推广计划 中宣布的那样,eslintrc 配置系统已在 ESLint v10.0.0 中完全移除。具体来说,这意味着

  1. ESLINT_USE_FLAT_CONFIG 环境变量不再被遵守。
  2. CLI 不再支持 eslintrc 特定的参数 (--no-eslintrc, --env, --resolve-plugins-relative-to, --rulesdir, --ignore-path)。
  3. .eslintrc.*.eslintignore 文件将不再被遵守。
  4. /* eslint-env */ 注释将被报告为错误。
  5. loadESLint() 函数现在始终返回 ESLint 类。
  6. Linter 构造函数的 configType 参数只能是 "flat",如果传递 "eslintrc" 将抛出错误。
  7. 以下 Linter eslintrc 特定的方法已被移除
    • defineParser()
    • defineRule()
    • defineRules()
    • getRules()
  8. 以下对 /use-at-your-own-risk 入口点的更改
    • LegacyESLint 已移除
    • FileEnumerator 已移除
    • shouldUseFlatConfig() 函数将始终返回 true

JSX 引用现在被跟踪

ESLint v10.0.0 现在跟踪 JSX 引用,从而能够正确分析 JSX 元素的作用域。

以前,JSX 标识符没有被跟踪为引用,这可能导致依赖作用域信息的规则产生不正确的结果。例如

import { Card } from "./card.jsx";

export function createCard(name) {
  return <Card name={name} />;
}

在 v10.0.0 之前

  • 误报<Card> 可能会被报告为“已定义但未被使用”(no-unused-vars)。
  • 漏报:移除导入可能不会触发“未定义变量”错误(no-undef)。

从 v10.0.0 开始,<Card> 被视为作用域中变量的正常引用。这消除了令人困惑的误报/漏报,使 JSX 处理与开发人员的期望保持一致,并改善了使用 JSX 的项目的 linting 体验。

Espree 和 ESLint Scope 现在包含类型

Espree v11.1.0ESLint Scope v9.1.0 开始,这些包现在包含内置类型定义。

以前,类型定义由 Definitely Typed 包 @types/espree@types/eslint-scope 提供。旧类型定义和新类型定义之间存在一些差异,主要是错误修复。如果您的代码依赖于 Espree 和 ESLint Scope 包的类型,请检查是否需要进行任何更新。

RuleTester 的增强

自 ESLint 早期以来,ESLint 一直提供 RuleTester API,以帮助插件作者针对自定义测试用例和配置测试他们的规则。此版本引入了 RuleTester 的几个增强功能,以强制执行更强大的测试定义并改善调试。

断言选项

RuleTester#run() 方法现在支持 断言选项,特别是 requireMessagerequireLocationrequireData,让开发人员可以强制在规则测试中执行更严格的要求。这些选项强制每个无效测试用例显式检查违规消息、位置和数据,确保如果测试不满足要求,则测试将失败。

  • requireMessage

    • 确保每个测试用例都包含消息检查。
    • 接受
      • true:必须使用对象数组来检查 errors,而不是数字计数简写,以检查规则报告的问题。每个对象必须包含一个 messagemessageId 属性,以检查报告问题的消息。
      • "message":必须仅使用 message 进行检查。
      • "messageId":必须仅使用 messageId 进行检查。
    • 目的: 防止测试在未验证实际消息的情况下通过。
  • requireLocation

    • 确保每个测试用例都包含位置检查。
    • 接受:true
    • 要求 errors 数组中的每个对象都包含 linecolumn
    • 如果实际报告不包含它们,则 endLineendColumn 是可选的。
    • 目的: 保证测试验证错误的地点。
  • requireData

    • 确保每个测试用例都包含 data 检查。
    • 接受:true
    • 当设置为 true 时,RuleTester 将要求无效测试用例在 messageId 引用带有占位符的消息时包含 data 对象。这有助于确保测试与依赖占位符替换的规则消息保持一致。

示例用法

ruleTester.run("my-rule", rule, {
  valid: [
    { code: "var foo = true;" }
  ],
  invalid: [
    {
      code: "var invalidVariable = true;",
      errors: [
        { message: "Unexpected invalid variable.", line: 1, column: 5 }
      ]
    }
  ],
  assertionOptions: {
    requireMessage: true,
    requireLocation: true
  }
});

改进失败测试的位置报告

RuleTester 现在用信息装饰堆栈跟踪,这使得更容易在您的源代码中找到失败的测试用例。例如,测试输出现在将包含堆栈跟踪行,指示失败测试用例在 invalid 数组中的索引以及定义该测试用例的文件和行号。

请注意,这些行号并不总是包含的,具体取决于您的测试结构。当无法精确确定行号时,失败的测试索引和打印的代码片段仍然可用于找到测试用例。

max-params 规则中的 countThis 选项

max-params 规则现在支持新的 countThis 选项,该选项取代了弃用的 countVoidThis。使用设置 countThis: "never",该规则现在将忽略 TypeScript 函数的参数列表中任何 this 注释,并在计算函数参数数量时忽略它。例如

function doSomething(this: SomeType, first: string, second: number) {
 // ...
}

将被视为一个只接受 2 个参数的函数。

格式化程序上下文中的 color 属性

当在命令行中指定 --color--no-color 选项时,ESLint 会在传递给格式化程序(format() 方法的第二个参数)的上下文对象上设置一个额外的 color 属性。此属性对于 --colortrue,对于 --no-colorfalse自定义格式化程序 可以使用此值来确定是否应用颜色样式,基于终端是否支持颜色,如选项所示。

更新了 eslint:recommended

eslint:recommended 配置 已更新为包含新的规则,我们认为这些规则很重要。

移除了已弃用的规则 context 成员

以下规则 context 成员不再可用

  • context.getCwd() - 使用 context.cwd 代替
  • context.getFilename() - 使用 context.filename 代替
  • context.getPhysicalFilename() - 使用 context.physicalFilename 代替
  • context.getSourceCode() - 使用 context.sourceCode 代替
  • context.parserOptions - 使用 context.languageOptionscontext.languageOptions.parserOptions 代替
  • context.parserPath - 没有替代方案

移除了已弃用的 SourceCode 方法

以下 SourceCode 方法不再可用

  • getTokenOrCommentBefore() - 使用 getTokenBefore() 并使用 { includeComments: true } 选项代替
  • getTokenOrCommentAfter() - 使用 getTokenAfter() 并使用 { includeComments: true } 选项代替
  • isSpaceBetweenTokens() - 使用 isSpaceBetween() 代替
  • getJSDocComment() - 没有替代方案

Program AST 节点范围跨越整个源代码

从 ESLint v10.0.0 开始,Program AST 节点的范围 跨越整个源代码。以前,前导和尾随注释/空格不包含在范围内。

Jiti < v2.2.0 不再支持

ESLint v10.0.0 停止支持当加载 TypeScript 配置文件时,早于 2.2.0 的 jiti 版本,因为已知问题可能导致兼容性问题,当配置加载某些插件时会出现兼容性问题。

破坏性更改

  • f9e54f4 feat!: 估计 rule-tester 失败位置 (#20420) (ST-DDT)
  • a176319 feat!: 替换 chalkstyleText 并将 color 添加到 ResultsMeta (#20227) (루밀LuMir)
  • c7046e6 feat!: 启用 JSX 引用跟踪 (#20152) (Pixel998)
  • fa31a60 feat!: 添加配置的 name (#20015) (Kirk Waiblinger)
  • 3383e7e fix!: 移除已弃用的 SourceCode 方法 (#20137) (Pixel998)
  • 501abd0 feat!: 更新依赖 minimatch 到 v10 (#20246) (renovate[bot])
  • ca4d3b4 fix!: 更严格的 rule tester 断言,用于有效的测试用例 (#20125) (唯然)
  • 96512a6 fix!: 移除已弃用的规则 context 方法 (#20086) (Nicholas C. Zakas)
  • c69fdac feat!: 移除 eslintrc 支持 (#20037) (Francesco Trotta)
  • 208b5cc feat!: 使用 ScopeManager#addGlobals() (#20132) (Milos Djermanovic)
  • a2ee188 fix!: 在 no-invalid-regexp 选项中添加 uniqueItems: true (#20155) (Tanuj Kanti)
  • a89059d feat!: 程序范围跨越整个源代码文本 (#20133) (Pixel998)
  • 39a6424 fix!: 断言所有 RuleFixer 方法中的 ‘text’ 都是字符串 (#20082) (Pixel998)
  • f28fbf8 fix!: 弃用 "always""as-needed" 选项的 radix 规则 (#20223) (Milos Djermanovic)
  • aa3fb2b fix!: 强化 func-names 模式 (#20119) (Pixel998)
  • f6c0ed0 feat!: 将 eslint-env 注释报告为错误 (#20128) (Francesco Trotta)
  • 4bf739f fix!: 移除已弃用的 LintMessage#nodeTypeTestCaseError#type (#20096) (Pixel998)
  • 523c076 feat!: 停止支持 jiti < 2.2.0 (#20016) (michael faith)
  • 454a292 feat!: 更新 eslint:recommended 配置 (#20210) (Pixel998)
  • 4f880ee feat!: 移除 v10_* 和非活动的 unstable_* 标志 (#20225) (sethamus)
  • f18115c feat!: no-shadow-restricted-names 默认报告 globalThis (#20027) (sethamus)
  • c6358c3 feat!: 要求 Node.js ^20.19.0 || ^22.13.0 || >=24 (#20160) (Milos Djermanovic)

特性

错误修复

  • 436b82f fix: 更新 eslint (#20473) (renovate[bot])
  • 1d29d22 fix: 检测 Array.fromAsync 回调中的默认 this 绑定 (#20456) (Francesco Trotta)
  • 727451e fix: 修复全局模式报告范围在 strict 规则中的回归 (#20462) (ntnyq)
  • e80485f fix: 移除假的 FlatESLintLegacyESLint 导出 (#20460) (Francesco Trotta)
  • 9eeff3b fix: 更新 esquery (#20423) (cryptnix)
  • b34b938 fix: 使用 Error.prepareStackTrace 估算失败的测试位置 (#20436) (Francesco Trotta)
  • 51aab53 fix: 更新 eslint (#20443) (renovate[bot])
  • 23490b2 fix: 处理 RuleTester 位置估计中的冒号前的空格 (#20433) (Francesco Trotta)
  • f244dbf fix: 使用来自 @eslint/coreMessagePlaceholderData 类型 (#20348) (루밀LuMir)
  • d186f8c fix: 更新 eslint (#20427) (renovate[bot])
  • 2332262 fix: 错误位置不应修改 RuleTester 中的错误消息 (#20421) (Milos Djermanovic)
  • ab99b21 fix: 确保将 filename 作为第三个参数传递给 verifyAndFix() (#20405) (루밀LuMir)
  • 8a60f3b fix: 从 ParserOptions 类型中移除 ecmaVersionsourceType (#20415) (Pixel998)
  • eafd727 fix: 移除 TDZ 作用域类型 (#20231) (jaymarvelz)
  • 39d1f51 fix: 修正 Scope 类型 (#20404) (sethamus)
  • 2bd0f13 fix: 更新 verifyverifyAndFix 类型 (#20384) (Francesco Trotta)
  • ba6ebfa fix: 修正 loadESLint()shouldUseFlatConfig() 的类型 (#20393) (루밀LuMir)
  • e7673ae fix: 修正 RuleTester 类型 (#20105) (Pixel998)
  • 53e9522 fix: strict 移除格式化程序检查 (#20241) (ntnyq)
  • b017f09 fix: 修正 no-restricted-import 消息 (#20374) (Francesco Trotta)

文档

  • e978dda docs: 更新 README (GitHub Actions Bot)
  • 4cecf83 docs: 更新 README (GitHub Actions Bot)
  • c79f0ab docs: 更新 README (GitHub Actions Bot)
  • 773c052 docs: 更新 README (GitHub Actions Bot)
  • f2962e4 docs: 记录 meta.docs.frozen 属性 (#20475) (Pixel998)
  • 8e94f58 docs: 修复动词形式标题更新后的损坏的锚链接 (#20449) (Copilot)
  • 1495654 docs: 更新 README (GitHub Actions Bot)
  • 0b8ed5c docs: 记录对 :is 选择器别名的支持 (#20454) (sethamus)
  • 1c4b33f docs: 记录有关仅 ESM 依赖项的策略 (#20448) (Milos Djermanovic)
  • 3e5d38c docs: 在规则示例中添加缺少的缩进空格 (#20446) (fnx)
  • 63a0c7c docs: 更新 README (GitHub Actions Bot)
  • 65ed0c9 docs: 更新 README (GitHub Actions Bot)
  • b0e4717 docs: [no-await-in-loop] 扩展不适用性 (#20363) (Niklas Hambüchen)
  • fca421f docs: 更新 README (GitHub Actions Bot)
  • d925c54 docs: 更新 no-lone-blocks 中的配置语法 (#20413) (Pixel998)
  • 7d5c95f docs: 移除规则示例中的冗余 sourceType: "module" (#20412) (Pixel998)
  • 02e7e71 docs: 修正带有扩展名的文件示例中的 .mts glob 模式 (#20403) (Ali Essalihi)
  • 264b981 docs: 更新 README (GitHub Actions Bot)
  • 5a4324f docs: 澄清 no-unused-vars"local" 选项 (#20385) (Milos Djermanovic)
  • e593aa0 docs: 改进文档站点 README 的清晰度、语法和措辞 (#20370) (Aditya)
  • 3f5062e docs: 将 messages 属性添加到规则 meta 文档 (#20361) (Sabya Sachi)
  • 9e5a5c2 docs: 移除规则文档中的 Examples 标题 (#20364) (Milos Djermanovic)
  • 194f488 docs: 更新 README (GitHub Actions Bot)
  • 0f5a94a docs: [class-methods-use-this] 解释规则的目的 (#20008) (Kirk Waiblinger)
  • df5566f 文档:为所有规则文档添加“选项”部分 (#20296) (sethamus)
  • adf7a2b 文档:为生成器函数添加 no-unsafe-finally 注释 (#20330) (Tom Pereira)
  • ef7028c 文档:更新 README (GitHub Actions Bot)
  • fbae5d1 文档:在迁移指南中一致使用“v10.0.0” (#20328) (Pixel998)
  • 778aa2d 文档:忽略默认文件模式 (#20312) (Tanuj Kanti)
  • 4b5dbcd 文档:重新排序 v10 迁移指南 (#20315) (Milos Djermanovic)
  • 5d84a73 文档:更新 README (GitHub Actions Bot)
  • 37c8863 文档:修复 v10 迁移指南中的不正确的锚链接 (#20299) (Pixel998)
  • 077ff02 文档:添加迁移到 10.0.0 的文档 (#20143) (唯然)
  • 3822e1b 文档:更新 README (GitHub Actions Bot)
  • 9f08712 构建:更新 10.0.0-rc.2 的 changelog (Jenkins)
  • 1e2c449 构建:更新 10.0.0-rc.1 的 changelog (Jenkins)
  • c4c72a8 构建:更新 10.0.0-rc.0 的 changelog (Jenkins)
  • 7e4daf9 构建:更新 10.0.0-beta.0 的 changelog (Jenkins)
  • a126a2a 构建:将 .scss 文件条目添加到 knip (#20389) (Francesco Trotta)
  • f5c0193 构建:更新 10.0.0-alpha.1 的 changelog (Jenkins)
  • 165326f 构建:更新 10.0.0-alpha.0 的 changelog (Jenkins)

杂项

  • 1ece282 杂项:在链接检查器中忽略 /docs/v9.x (#20452) (Milos Djermanovic)
  • 034e139 ci:为 @html-eslint/eslint-plugin 添加类型集成测试 (#20345) (sethamus)
  • f3fbc2f 杂项:将 @eslint/js 版本设置为 10.0.0 以跳过发布 (#20466) (Milos Djermanovic)
  • afc0681 杂项:移除 typescript-eslint 解析器中的 scopeManager.addGlobals 补丁 (#20461) (fnx)
  • 3e5a173 重构:使用来自 @eslint/plugin-kit 的类型 (#20435) (Pixel998)
  • 11644b1 ci:重命名工作流 (#20463) (Milos Djermanovic)
  • 2d14173 杂项:修复文档和注释中的拼写错误 (#20458) (o-m12a)
  • 6742f92 测试:为 no-alert 中的无效测试用例添加 endLine/endColumn (#20441) (경하)
  • 3e22c82 测试:为 no-template-curly-in-string 测试添加缺失的位置数据 (#20440) (Haeun Kim)
  • b4b3127 杂项:为 @eslint/js 发布更新 package.json (Jenkins)
  • f658419 重构:移除 JS 语言中的 raw 解析器选项 (#20416) (Pixel998)
  • 2c3efb7 杂项:移除类型测试固定装置中的 category (#20417) (Pixel998)
  • 36193fd 杂项:移除格式化程序测试固定装置中的 category (#20418) (Pixel998)
  • e8d203b 杂项:将 JSX 语言标签验证添加到 check-rule-examples (#20414) (Pixel998)
  • bc465a1 杂项:固定依赖项 (#20397) (renovate[bot])
  • 703f0f5 测试:替换 linter 测试中的弃用规则 (#20406) (루밀LuMir)
  • ba71baa 测试:在类型测试中启用 strict 模式 (#20398) (루밀LuMir)
  • f9c4968 重构:移除 lib/linter/rules.js (#20399) (Francesco Trotta)
  • 6f1c48e 杂项:为 v9.39.2 版本更新 (Jenkins)
  • 54bf0a3 ci:创建包管理器测试 (#20392) (루밀LuMir)
  • 3115021 重构:简化 JSDoc 注释检测逻辑 (#20360) (Pixel998)
  • 4345b17 杂项:更新 @eslint-community/regexpp4.12.2 (#20366) (루밀LuMir)
  • 772c9ee 杂项:更新依赖项 @eslint/eslintrc 到 ^3.3.3 (#20359) (renovate[bot])
  • 0b14059 杂项:为 @eslint/js 发布更新 package.json (Jenkins)
  • d6e7bf3 ci:将 actions/checkout 从 5 升级到 6 (#20350) (dependabot[bot])
  • 139d456 杂项:在规则文档中需要强制标题 (#20347) (Milos Djermanovic)
  • 3b0289c 杂项:移除冗余的 .eslintignore 和测试固定装置 (#20316) (Pixel998)
  • a463e7b 杂项:更新依赖项 js-yaml 到 v4 [安全] (#20319) (renovate[bot])
  • ebfe905 杂项:移除 eslint-config-eslint 中的冗余规则 (#20327) (Milos Djermanovic)
  • 88dfdb2 测试:为消息占位符插值添加回归测试 (#20318) (fnx)
  • 6ed0f75 杂项:跳过 eslint-config-eslint 中的类型检查 (#20323) (Francesco Trotta)
  • 1e2cad5 杂项:为 @eslint/js 发布更新 package.json (Jenkins)
  • 9da2679 杂项:更新 @eslint/* 依赖项 (#20321) (Milos Djermanovic)
  • 0439794 重构:使用来自 @eslint/core 的类型 (#20235) (jaymarvelz)
  • cb51ec2 测试:清理 SourceCode#traverse 测试 (#20289) (Milos Djermanovic)
  • 897a347 杂项:移除规则测试中的 type 限制 (#20305) (Pixel998)
  • d972098 杂项:忽略 prettier 更新以与 trunk 同步 (#20304) (Pixel998)
  • a086359 杂项:移除冗余的 fast-glob 开发依赖项 (#20301) (루밀LuMir)
  • 564b302 杂项:将 prettier 安装为开发依赖项 (#20302) (michael faith)
  • 8257b57 重构:更正 eslint-plugin/report-message-format 的正则表达式 (#20300) (루밀LuMir)
  • e251671 重构:提取 RuleTester 中的断言 (#20135) (唯然)
  • 2e7f25e 杂项:将 legacy-peer-deps 添加到 .npmrc (#20281) (Milos Djermanovic)
  • 39c638a 杂项:更新 eslint-config-eslint 依赖项以用于 v10 预发布版 (#20278) (Milos Djermanovic)
  • 8533b3f 杂项:更新依赖项 @eslint/json 到 ^0.14.0 (#20288) (renovate[bot])
  • 796ddf6 杂项:更新依赖项 @eslint/js 到 ^9.39.1 (#20285) (renovate[bot])

最新的 ESLint 新闻、案例研究、教程和资源。

ESLint v10.0.0-rc.2 released
1 分钟阅读

ESLint v10.0.0-rc.2 发布

我们刚刚发布了 ESLint v10.0.0-rc.2,这是 ESLint 的补丁版本升级。此版本修复了先前版本中发现的几个错误。

ESLint v10.0.0-rc.1 released
2 分钟阅读

ESLint v10.0.0-rc.1 发布

我们刚刚发布了 ESLint v10.0.0-rc.1,这是 ESLint 的次要版本升级。此版本添加了一些新功能并修复了先前版本中发现的几个错误。

ESLint's 2025 year in review
5 分钟阅读

ESLint 的 2025 年回顾

2025 年见证了 ESLint 向 CSS 和 HTML 的扩展、多线程 linting 的引入以及迈向 v10.0.0 的第一步。