版本

迁移到 v6.0.0

ESLint v6.0.0 是 ESLint 的一个主要版本。我们在本次发布中做了一些重大更改。本指南旨在引导您了解这些重大更改。

以下列表大致按每个更改预计影响的用户数量排序,其中第一个项目预计影响的用户最多。

用户的重大更改

  1. 不再支持 Node.js 6
  2. eslint:recommended 已更新
  3. 插件和可共享配置不再受 ESLint 位置的影响
  4. 默认解析器现在更严格地验证选项
  5. 规则配置被更严格地验证
  6. no-redeclare 规则现在默认情况下更严格
  7. comma-dangle 规则现在默认情况下更严格
  8. no-confusing-arrow 规则现在默认情况下更宽松
  9. 配置文件中的 Overrides 现在可以匹配点文件
  10. 扩展配置文件中的 Overrides 现在可以被父配置文件覆盖
  11. globals 的配置值现在被验证
  12. 已弃用的 experimentalObjectRestSpread 选项已被移除
  13. 规则选项中用户提供的正则表达式使用 unicode 标志解析

插件/自定义规则开发者的重大更改

  1. 插件作者可能需要更新安装说明
  2. RuleTester 现在针对规则模式中的无效 default 关键字进行验证
  3. RuleTester 现在要求 parser 选项上使用绝对路径
  4. eslintExplicitGlobalComment 作用域分析属性已被移除

集成开发者的重大更改

  1. 插件和可共享配置不再受 ESLint 位置的影响
  2. Linter 不再尝试从文件系统加载丢失的解析器

不再支持 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 在某些情况下随机无法加载插件和可共享配置,尤其是在使用诸如 lernaYarn 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 配置的所有值都是 readonlywritableoff。(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

更改语言