ESLint v10.0.0 正式发布
发布时间:2026年2月6日 分类:Release Notes
我们刚刚发布了 ESLint v10.0.0,这是 ESLint 的一个重大版本升级。此版本增加了一些新特性,修复了上一版本中发现的若干 Bug。同时,本版本包含一些破坏性变更(Breaking Changes),请务必仔细阅读以下内容。
🌟 更新亮点
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 现在会从每个被检查文件所在的目录开始查找 eslint.config.*,而不是像 ESLint v9.x 那样从当前工作目录(CWD)开始。这种新行为允许在同一次运行中使用多个配置文件,对于 Monorepo(单一代码仓库)设置特别有用。
在 ESLint v9.x 中,可以通过 v10_config_lookup_from_file 特性标志(feature flag)启用此行为。在 ESLint v10.0.0 中,这已成为默认行为,且 v10_config_lookup_from_file 标志已被移除。
彻底移除 eslintrc 功能
正如在《Flat Config 推广计划》中宣布的那样,eslintrc 配置系统在 ESLint v10.0.0 中已被彻底移除。具体来说,这意味着:
-
不再尊崇
ESLINT_USE_FLAT_CONFIG环境变量。 -
CLI 不再支持
eslintrc特有的参数(如--no-eslintrc,--env,--resolve-plugins-relative-to,--rulesdir,--ignore-path)。 -
.eslintrc.*和.eslintignore文件将不再生效。 -
/* eslint-env */注释将被报告为错误。 -
loadESLint()函数现在总是返回ESLint类。 -
Linter构造函数的configType参数只能是"flat",如果传入"eslintrc"将抛出错误。 -
移除了以下
Linter的eslintrc特有方法: -
defineParser() -
defineRule() -
defineRules() -
getRules() -
/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 之前:
- 误报(False positives):
<Card>可能会被报告为“定义了但未使用”(no-unused-vars)。 - 漏报(False negatives): 移除 import 可能不会触发“未定义变量”错误(
no-undef)。
从 v10.0.0 开始,<Card> 被视为作用域内对该变量的正常引用。这消除了一样困扰开发者的误报/漏报问题,使 JSX 处理符合开发者预期,并改善了使用 JSX 项目的 linting 体验。
Espree 和 ESLint Scope 现包含类型定义
从 Espree v11.1.0 和 ESLint Scope v9.1.0 开始,这些包现在包含内置的类型定义。
此前,类型定义由 Definitely Typed 包 @types/espree 和 @types/eslint-scope 提供。旧版和新版类型定义之间存在一些差异,主要是 bug 修复。如果你的代码依赖 Espree 和 ESLint Scope 包的类型,请检查是否需要更新。
RuleTester 的增强
自诞生之初,ESLint 就提供了 RuleTester API,帮助插件作者针对自定义测试用例和配置测试其规则。此版本对 RuleTester 进行了多项增强,以强制执行更健壮的测试定义并改进调试体验。
断言选项 (Assertion options)
RuleTester#run() 方法现在支持断言选项,特别是 requireMessage、requireLocation 和 requireData,允许开发者在规则测试中强制执行更严格的要求。这些选项强制每个无效(invalid)测试用例显式检查违规消息、位置和数据,确保如果测试不符合要求则失败。
-
requireMessage:确保每个测试用例都包含消息检查。 -
接受
true(必须使用对象数组检查errors)、"message"或"messageId"。 -
目的:防止测试在未验证实际消息的情况下通过。
-
requireLocation:确保每个测试用例都包含位置检查。 -
接受
true。要求errors数组中的每个对象都有line和column。 -
目的:保证测试验证了错误的位置。
-
requireData:确保每个测试用例都包含数据检查。 -
接受
true。当messageId引用带有占位符的消息时,要求无效测试用例包含data对象。
改进失败测试的位置报告
RuleTester 现在会在堆栈跟踪中修饰信息,使其更容易在源代码中定位失败的测试用例。例如,测试输出现在将包含堆栈跟踪行,指示 invalid 数组中失败测试用例的索引以及该测试用例定义所在的文件和行号。
max-params 规则中的 countThis 选项
max-params 规则现在支持新的 countThis 选项,该选项取代了已弃用的 countVoidThis。设置 countThis: "never" 后,规则在计算 TypeScript 函数参数数量时将忽略函数参数列表中的 this 注解。
例如:
function doSomething(this: SomeType, first: string, second: number) {
// ...
}
这将被视为仅接受 2 个参数的函数。
Formatter 上下文中的 color 属性
当在命令行中指定 --color 或 --no-color 时,ESLint 会在传递给 formatter(format() 方法的第二个参数)的上下文对象上设置一个额外的 color 属性。
--color时为true--no-color时为false
自定义 formatter 可以利用此值来决定是否应用颜色样式。
更新 eslint:recommended
eslint:recommended 配置已更新,包含了一些我们认为重要的新规则。
移除已弃用的规则上下文成员
以下规则上下文(Rule Context)成员不再可用:
context.getCwd()- 请改用context.cwdcontext.getFilename()- 请改用context.filenamecontext.getPhysicalFilename()- 请改用context.physicalFilenamecontext.getSourceCode()- 请改用context.sourceCodecontext.parserOptions- 请改用context.languageOptions或context.languageOptions.parserOptionscontext.parserPath- 无替代品
移除已弃用的 SourceCode 方法
以下 SourceCode 方法不再可用:
getTokenOrCommentBefore()- 请改用getTokenBefore()并带上{ includeComments: true }选项getTokenOrCommentAfter()- 请改用getTokenAfter()并带上{ includeComments: true }选项isSpaceBetweenTokens()- 请改用isSpaceBetween()getJSDocComment()- 无替代品
Program AST 节点范围覆盖整个源文本
从 ESLint v10.0.0 开始,Program AST 节点的范围(range)涵盖整个源文本。此前,前导和尾随的注释/空白不包含在范围内。
不再支持 Jiti < v2.2.0
ESLint v10.0.0 在加载 TypeScript 配置文件时不再支持 2.2.0 版本之前的 jiti,因为已知存在导致配置加载某些插件时出现兼容性问题的 bug。
🛠 变更日志 (Changelog)
💥 破坏性变更 (Breaking Changes)
feat!: 估算 rule-tester 失败位置feat!: 用 styleText 替换 chalk 并向 ResultsMeta 添加 colorfeat!: 启用 JSX 引用追踪feat!: 为配置添加 name 属性fix!: 移除已弃用的 SourceCode 方法feat!: 更新依赖 minimatch 到 v10fix!: 对有效测试用例进行更严格的 rule tester 断言fix!: 移除已弃用的 rule context 方法feat!: 移除 eslintrc 支持feat!: 使用 ScopeManager#addGlobals()fix!: 在 no-invalid-regexp 选项中添加 uniqueItems: truefeat!: Program 范围覆盖整个源文本fix!: 在所有 RuleFixer 方法中断言 'text' 是字符串fix!: 弃用 radix 规则的 "always" 和 "as-needed" 选项fix!: 收紧 func-names schemafeat!: 将 eslint-env 注释报告为错误fix!: 移除已弃用的 LintMessage#nodeType 和 TestCaseError#typefeat!: 放弃对 jiti < 2.2.0 的支持feat!: 更新 eslint:recommended 配置feat!: 移除 v10_* 和不活跃的 unstable_* 标志feat!: no-shadow-restricted-names 默认报告 globalThisfeat!: 要求 Node.js ^20.19.0 || ^22.13.0 || >=24
✨ 新特性 (Features)
feat: 在 array-callback-return 中处理 Array.fromAsyncfeat: 向 no-implied-eval 规则添加 selffeat: 修复 no-shadow 中函数和类表达式名称的处理feat: rule tester 添加断言选项 requireDatafeat: 输出 RuleTester 测试用例失败索引feat: 向 max-params 添加 countThis 选项feat: 添加错误断言选项 (requireMessage, requireLocation)feat: 更新 require-yield 和 no-useless-constructor 的错误位置
🐛 Bug 修复 (Bug Fixes)
fix: 检测 Array.fromAsync 回调中的默认 this 绑定fix: 修复 strict 规则中全局模式报告范围的回归问题fix: 移除伪造的 FlatESLint 和 LegacyESLint 导出fix: 更新 esqueryfix: 使用 Error.prepareStackTrace 估算失败测试位置fix: 在 RuleTester 位置估算中处理冒号前的空格fix: 使用来自 @eslint/core 的 MessagePlaceholderData 类型fix: error location 不应修改 RuleTester 中的错误消息fix: 确保 filename 作为第三个参数传递给 verifyAndFix()fix: 从 ParserOptions 类型中移除 ecmaVersion 和 sourceTypefix: 移除 TDZ 作用域类型fix: 修正 Scope 类型定义fix: 更新 verify 和 verifyAndFix 类型fix: 修正 loadESLint() 和 shouldUseFlatConfig() 的类型定义fix: 修正 RuleTester 类型定义fix: 严格检查已移除的 formattersfix: 修正 no-restricted-import 消息