迁移到 v6.0.0
ESLint v6.0.0 是 ESLint 的一个主要版本。我们在本次发布中做了一些重大更改。本指南旨在引导您了解这些重大更改。
以下列表大致按每个更改预计影响的用户数量排序,其中第一个项目预计影响的用户最多。
用户的重大更改
- 不再支持 Node.js 6
eslint:recommended
已更新- 插件和可共享配置不再受 ESLint 位置的影响
- 默认解析器现在更严格地验证选项
- 规则配置被更严格地验证
no-redeclare
规则现在默认情况下更严格comma-dangle
规则现在默认情况下更严格no-confusing-arrow
规则现在默认情况下更宽松- 配置文件中的 Overrides 现在可以匹配点文件
- 扩展配置文件中的 Overrides 现在可以被父配置文件覆盖
- globals 的配置值现在被验证
- 已弃用的
experimentalObjectRestSpread
选项已被移除 - 规则选项中用户提供的正则表达式使用 unicode 标志解析
插件/自定义规则开发者的重大更改
- 插件作者可能需要更新安装说明
RuleTester
现在针对规则模式中的无效default
关键字进行验证RuleTester
现在要求parser
选项上使用绝对路径eslintExplicitGlobalComment
作用域分析属性已被移除
集成开发者的重大更改
不再支持 Node.js 6
截至 2019 年 4 月,Node.js 6 将达到 EOL,并且不再接收安全更新。因此,我们决定在 ESLint v6 中放弃对其的支持。我们现在支持以下版本的 Node.js
- Node.js 8 (8.10.0 及以上)
- Node.js 10 (10.13.0 及以上)
- Node.js 11.10.1 以上的任何版本
要解决: 确保在使用 ESLint v6 时升级到至少 Node.js 8。如果您无法升级,我们建议继续使用 ESLint v5.x,直到您能够升级 Node.js。
相关问题: eslint/eslint#11546
eslint:recommended
已更新
以下规则已添加到 eslint:recommended
配置中
no-async-promise-executor
禁止使用async
函数作为Promise
构造函数的参数,这通常是一个错误。no-misleading-character-class
报告正则表达式中可能表现不符合预期的字符类。no-prototype-builtins
报告诸如foo.hasOwnProperty("bar")
之类的方法调用(这是错误的常见来源),并建议将其替换为Object.prototype.hasOwnProperty.call(foo, "bar")
。no-shadow-restricted-names
禁止遮蔽诸如undefined
之类的变量(例如使用像let undefined = 5;
这样的代码),因为这很可能会使读者感到困惑。no-useless-catch
报告冗余的catch
子句,可以从代码中删除而不会改变其行为。no-with
禁止使用with
语句,这会使代码难以理解并导致兼容性问题。require-atomic-updates
报告在异步函数中重新分配变量时可能发生的竞争条件错误。
此外,以下规则已从 eslint:recommended
中移除
no-console
禁止调用诸如console.log
之类的函数。虽然此规则在许多情况下很有用(例如,避免无意中将调试语句留在生产代码中),但它不如eslint:recommended
中的其他规则那样具有广泛的适用性,并且在console.log
可以接受的情况下(例如,在 CLI 应用程序中),它是误报的来源。
最后,在 ESLint v5 中,eslint:recommended
会显式禁用所有未被视为“推荐”的核心规则。如果 eslint:recommended
在另一个配置之后加载,这可能会导致令人困惑的行为,因为 eslint:recommended
会产生关闭某些规则的效果。在 ESLint v6 中,eslint:recommended
对非推荐规则没有影响。
要解决: 要模仿 5.x 中的 eslint:recommended
行为,您可以在配置文件中显式禁用/启用规则,如下所示
{
"extends": "eslint:recommended",
"rules": {
"no-async-promise-executor": "off",
"no-misleading-character-class": "off",
"no-prototype-builtins": "off",
"no-shadow-restricted-names": "off",
"no-useless-catch": "off",
"no-with": "off",
"require-atomic-updates": "off",
"no-console": "error"
}
}
在极少数情况下(如果您依赖于 eslint:recommended
禁用核心规则的先前行为),您可能需要禁用其他规则以恢复先前的行为。
相关问题: eslint/eslint#10768, eslint/eslint#10873
插件和可共享配置不再受 ESLint 位置的影响
以前,ESLint 相对于 ESLint 包本身的位置加载插件。因此,我们建议全局安装 ESLint 的用户也应该全局安装插件,而本地安装 ESLint 的用户应该本地安装插件。但是,由于设计缺陷,此策略导致 ESLint 在某些情况下随机无法加载插件和可共享配置,尤其是在使用诸如 lerna
和 Yarn Plug n’ Play 之类的包管理工具时。
作为经验法则:使用 ESLint v6,插件应始终本地安装,即使 ESLint 是全局安装的。更准确地说,ESLint v6 默认情况下相对于最终用户的项目解析插件,并且始终相对于导入它们配置文件的位置解析可共享配置和解析器。
要解决: 如果您使用 ESLint 的全局安装(例如,使用 npm install eslint --global
安装)以及插件,则应在运行 ESLint 的项目中本地安装这些插件。如果您的配置文件扩展了可共享配置和/或解析器,则应确保这些软件包作为包含配置文件的项目的依赖项安装。
如果您使用位于本地项目之外的配置文件(使用 --config
标志),请考虑将插件作为该配置文件的依赖项安装,并将 --resolve-plugins-relative-to
标志设置为配置文件的位置。
相关问题: eslint/eslint#10125, eslint/rfcs#7
默认解析器现在更严格地验证选项
espree
,ESLint 使用的默认解析器,现在将在以下情况下引发错误
ecmaVersion
解析器选项设置为非数字,例如字符串"2015"
。(以前,非数字选项将被忽略。)- 当
ecmaVersion
设置为5
或未指定时,设置了sourceType: "module"
解析器选项。(以前,设置sourceType: "module"
会隐式地将ecmaVersion
设置为至少 2015,这可能会令人惊讶。) sourceType
设置为"script"
或"module"
以外的任何值。
要解决: 如果您的配置将 ecmaVersion
设置为非数字,则可以通过删除 ecmaVersion
来恢复先前的行为。(但是,您可能需要仔细检查您的配置是否实际上按预期工作。)如果您的配置设置了 parserOptions: { sourceType: "module" }
而没有同时设置 parserOptions.ecmaVersion
,则应添加 parserOptions: { ecmaVersion: 2015 }
以恢复先前的行为。
相关问题: eslint/eslint#9687, eslint/espree#384
规则配置被更严格地验证
为了更早地捕获配置错误,如果您尝试配置不存在的规则,ESLint v6 将报告 lint 错误。
配置 | ESLint v5 | ESLint v6 |
---|---|---|
/*eslint-enable foo*/ |
无错误 | lint 错误 |
/*eslint-disable(-line) foo*/ |
无错误 | lint 错误 |
/*eslint foo: 0*/ |
无错误 | lint 错误 |
{rules: {foo: 0}} |
无错误 | 无错误 |
{rules: {foo: 1} |
lint 警告 | lint 错误 |
要解决: 您可以删除(内联)配置中不存在的规则。
相关问题: eslint/eslint#9505
no-redeclare
规则现在默认情况下更严格
no-redeclare
规则的默认选项已从 { builtinGlobals: false }
更改为 { builtinGlobals: true }
。此外,如果全局变量已通过配置启用,则 no-redeclare
规则现在将为通过类似 /* global foo */
的注释启用的全局变量报告错误。
要解决
要恢复规则的先前选项,您可以按如下方式配置它
{
"rules": {
"no-redeclare": ["error", { "builtinGlobals": false }]
}
}
此外,如果您在代码中看到新的 global
注释错误,则应删除这些注释。
相关问题: eslint/eslint#11370, eslint/eslint#11405
comma-dangle
规则现在默认情况下更严格
以前,comma-dangle
规则会忽略尾随的函数参数和参数,除非显式配置为检查函数逗号。在 ESLint v6 中,函数逗号的处理方式与其他类型的尾随逗号相同。
要解决: 您可以使用以下内容恢复规则的先前默认行为
{
"rules": {
"comma-dangle": ["error", {
"arrays": "never",
"objects": "never",
"imports": "never",
"exports": "never",
"functions": "ignore"
}]
}
}
要恢复像 "always-multiline"
这样的字符串选项的先前行为,请在上面的示例中将 "never"
替换为 "always-multiline"
。
相关问题: eslint/eslint#11502
no-confusing-arrow
规则现在默认情况下更宽松
no-confusing-arrow
规则的默认选项已从 { allowParens: false }
更改为 { allowParens: true }
。
要解决: 您可以使用以下内容恢复规则的先前默认行为
{
"rules": {
"no-confusing-arrow": ["error", { "allowParens": false }]
}
}
相关问题: eslint/eslint#11503
配置文件中的 Overrides 现在可以匹配点文件
由于一个错误,配置文件 overrides
部分中 files
列表中的 glob 模式永远不会匹配点文件,这使得无法让 overrides 应用于以点开头的文件。此错误已在 ESLint v6 中修复。
要解决: 如果您不希望点文件被 override 匹配,请考虑向该 overrides
部分添加类似 excludedFiles: [".*"]
的内容。有关更多详细信息,请参阅 文档。
相关问题: eslint/eslint#11201
扩展配置文件中的 Overrides 现在可以被父配置文件覆盖
由于一个错误,先前共享配置中的 overrides
块优先于父配置文件的顶层。例如,使用以下配置设置,即使在最终用户的配置中显式禁用了 semi
规则,最终也会启用它
// .eslintrc.js
module.exports = {
extends: ["foo"],
rules: {
semi: "off"
}
};
// eslint-config-foo/index.js
module.exports = {
overrides: {
files: ["*.js"],
rules: {
semi: "error"
}
}
};
在 ESLint v6.0.0 中,父配置文件始终优先于扩展配置,即使使用 overrides
块也是如此。
要解决: 我们预计此问题的影响非常低,因为大多数可共享配置不使用 overrides
块。但是,如果您使用带有 overrides
块的可共享配置,您可能会遇到行为更改,原因是您的配置中明确指定了某些内容,但直到现在才处于活动状态。如果您希望从可共享配置继承行为,只需从您自己的配置中删除相应的条目即可。(在上面的示例中,可以通过从 .eslintrc.js
中删除 semi: "off"
来恢复先前的行为。)
相关问题: eslint/eslint#11510
globals 的配置值现在被验证
以前,当使用对象配置一组全局变量时,可以使用任何内容作为对象的值。未知值将被视为与 "writable"
相同。
// .eslintrc.js
module.exports = {
globals: {
foo: "readonly",
bar: "writable",
baz: "hello!" // ???
}
};
通过此更改,globals
对象中的任何未知值都会导致配置验证错误。
要解决: 如果您在更新后看到与 globals 相关的配置验证错误,请确保为 globals 配置的所有值都是 readonly
、writable
或 off
。(ESLint 还接受一些备用拼写和变体以实现兼容性。)
已弃用的 experimentalObjectRestSpread
选项已被移除
以前,当使用默认解析器时,配置可以使用 experimentalObjectRestSpread
选项来启用对对象 rest/spread 属性的解析支持
{
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
}
}
自 ESLint v5 以来,ecmaFeatures: { experimentalObjectRestSpread: true }
等同于 ecmaVersion: 2018
,并且还发出了弃用警告。在 ESLint v6 中,experimentalObjectRestSpread
功能已完全移除,并且不起作用。如果您的配置依赖于 experimentalObjectRestSpread
来启用 ES2018 解析,您可能会开始看到最近语法的解析错误。
要解决: 如果您使用 experimentalObjectRestSpread
选项,则应将您的配置更改为包含以下内容
{
"parserOptions": {
"ecmaVersion": 2018
}
}
如果您不确定需要更新哪个配置文件,运行 ESLint v5 并查看弃用警告中提到的配置文件可能会很有用。
相关问题: eslint/eslint#9990
规则选项中用户提供的正则表达式使用 unicode 标志解析
诸如 max-len
之类的规则接受一个字符串选项,该选项被解释为正则表达式。在 ESLint v6.0.0 中,这些正则表达式使用 unicode 标志 解释,当匹配像星号符号这样的字符时,应该表现出更合理的行为。Unicode 正则表达式还比非 unicode 正则表达式更严格地验证转义序列。
要解决: 如果您在升级后获得规则选项验证错误,请确保您的规则选项中的任何正则表达式都没有无效的转义序列。
相关问题: eslint/eslint#11423
插件作者可能需要更新安装说明
如果您维护一个插件并提供安装说明,则应确保安装说明与 插件加载方式的用户可见更改保持同步。特别是,如果您的插件是使用 generator-eslint
包生成的,则它可能包含关于如何将插件与全局 ESLint 安装一起使用的过时说明。
相关问题: eslint/rfcs#7
RuleTester
现在针对规则模式中的无效 default
关键字进行验证
在某些情况下,规则模式可以使用 default
关键字自动为规则选项指定默认值。但是,default
关键字仅在某些模式位置有效,而在其他位置则被忽略,如果在规则错误地期望默认值作为规则选项提供的情况下,这会造成错误风险。在 ESLint v6.0.0 中,如果规则在其模式中具有无效的 default
关键字,RuleTester
将引发错误。
要解决: 如果 RuleTester
开始报告关于无效默认值的错误,您可以删除规则模式中指示位置的 default
属性,并且规则的行为将相同。(如果发生这种情况,您可能还需要验证当该位置未提供选项值时,规则的行为是否正确。)
相关问题: eslint/eslint#11473
RuleTester
现在要求 parser
选项上使用绝对路径
为了在测试中使用自定义解析器,我们可以使用带有包名称或文件路径的 parser
属性。但是,如果给出了包名称,则不清楚测试程序应从何处加载解析器包,因为测试程序不知道哪些文件正在运行测试程序。在 ESLint v6.0.0 中,RuleTester
禁止带有包名称的 parser
属性。
要解决: 如果您在测试用例中使用带有包名称的 parser
属性,请使用 require.resolve()
函数更新它,以将包名称解析为包的绝对路径。
相关问题: eslint/eslint#11728, eslint/eslint#10125, eslint/rfcs#7
eslintExplicitGlobalComment
作用域分析属性已被移除
以前,ESLint 会将 eslintExplicitGlobalComment
属性添加到作用域分析中的 Variable
对象,以指示变量是由于 /* global */
注释而引入的。此属性未记录在案,ESLint 团队无法在 ESLint 核心之外找到该属性的任何用法。该属性已在 ESLint v6 中移除,并替换为 eslintExplicitGlobalComments
属性,如果变量使用多个 /* global */
注释声明,则该属性可以包含所有这些注释的列表。
要解决: 如果您维护一个使用 eslintExplicitGlobalComment
属性的规则,请将其更新为使用 eslintExplicitGlobalComments
属性作为列表。
相关问题: eslint/rfcs#17
Linter
不再尝试从文件系统加载丢失的解析器
以前,当使用先前未定义的解析器 lint 代码时,Linter
API 将尝试从文件系统加载解析器。但是,此行为令人困惑,因为 Linter
从不在任何其他情况下访问文件系统,并且很难确保在从文件系统加载解析器时会找到正确的解析器。
在 ESLint v6 中,Linter
将不再执行任何文件系统操作,包括加载解析器。
要解决: 如果您将 Linter
与自定义解析器一起使用,请使用 Linter#defineParser
在 lint 任何代码之前显式定义解析器。
相关问题: eslint/rfcs#7