版本

迁移到 v2.0.0

ESLint v2.0.0 是第二个主要版本发布。因此,在 ESLint 在 0.x 和 1.x 版本中的工作方式与未来版本的工作方式之间存在一些重大变化。这些变化是直接来自于 ESLint 用户社区的反馈,并且在充分考虑升级路径后才做出的。我们相信这些变化使 ESLint 变得更好,虽然升级需要做一些工作,但我们希望这次升级带来的痛苦足够小,让您能够看到升级的好处。

重要提示:如果您是从 0.x 版本升级,请参考 迁移到 1.0.0 作为您的起点。

规则 Schema 变更

由于规则 schema 工作方式的怪癖,如果选项足够复杂,您可能需要在规则 schema 中考虑规则的严重程度(0、1 或 2)。这将导致如下所示的 schema:

module.exports = {
    "type": "array",
    "items": [
        {
            "enum": [0, 1, 2]
        },
        {
            "enum": ["always", "never"]
        }
    ],
    "minItems": 1,
    "maxItems": 2
};

这对于规则开发者来说很困惑,因为规则似乎不应该负责验证自身的严重程度。在 2.0.0 版本中,规则不再需要检查自身的严重程度。

解决方法:如果您正在导出检查严重程度的规则 schema,则需要进行以下几项更改

  1. 从 schema 中移除严重程度
  2. minItems 从 1 调整为 0
  3. 通过减 1 来调整 maxItems

以下是上面 schema 正确转换后的样子

module.exports = {
    "type": "array",
    "items": [
        {
            "enum": ["always", "never"]
        }
    ],
    "minItems": 0,
    "maxItems": 1
};

移除的规则

以下规则已被弃用,并创建了新规则来替代它们。以下是已移除规则及其替代规则的列表

解决方法:您需要更新您的规则配置以使用新规则。ESLint v2.0.0 还会在您使用已移除的规则时发出警告,并建议替换规则。希望这能减少升级过程中的意外情况。

配置级联变更

在 2.0.0 之前,如果一个目录同时包含 .eslintrc 文件和一个带有 ESLint 配置信息的 package.json 文件,则这两个文件中的设置会合并在一起。在 2.0.0 版本中,仅使用 .eslintrc.* 文件中的设置,当两者都存在时,package.json 中的设置将被忽略。否则,package.json 仍然可以与 ESLint 配置一起使用,但前提是不能存在其他 .eslintrc.* 文件。

解决方法:如果您的同一个目录中同时存在 .eslintrc.* 和带有 ESLint 配置信息的 package.json,请将您的配置合并到其中一个文件中。

内置全局变量

在 2.0.0 之前,作为 ES6 标准化一部分的新全局变量(例如 PromiseMapSetSymbol)包含在内置全局环境中。例如,即使在 promises 不可用的 ES5 代码中,no-undef 也允许使用 Promise 构造函数,这可能会导致潜在问题。在 2.0.0 版本中,内置环境仅包含标准的 ES5 全局变量,新的 ES6 全局变量已移至 es6 环境。

解决方法:如果您正在编写 ES6 代码,如果您尚未这样做,请启用 es6 环境

// In your .eslintrc
{
    env: {
        es6: true
    }
}

// Or in a configuration comment
/*eslint-env es6*/

语言选项

在 2.0.0 之前,启用语言选项的方法是在您的配置中使用 ecmaFeatures。在 2.0.0 版本中

  • ecmaFeatures 属性现在位于顶层 parserOptions 属性下。
  • 所有 ECMAScript 6 ecmaFeatures 标志都已被移除,取而代之的是 parserOptions 下的 ecmaVersion 属性,可以将其设置为 3、5(默认)或 6。
  • ecmaFeatures.modules 标志已被 parserOptions 下的 sourceType 属性取代,可以将其设置为 "script"(默认)或 "module" 用于 ES6 模块。

解决方法:如果您在 ecmaFeatures 中使用任何 ECMAScript 6 功能标志,您需要改用 ecmaVersion: 6。ECMAScript 6 功能标志包括

如果您正在使用任何这些标志,例如

{
    ecmaFeatures: {
        arrowFunctions: true
    }
}

那么您应该使用 ecmaVersion 启用 ES6

{
    parserOptions: {
        ecmaVersion: 6
    }
}

如果您在 ecmaFeatures 中使用任何非 ES6 标志,您需要将这些标志移到 parserOptions 内部。例如

{
    ecmaFeatures: {
        jsx: true
    }
}

那么您应该将 ecmaFeatures 移到 parserOptions

{
    parserOptions: {
        ecmaFeatures: {
            jsx: true
        }
    }
}

如果您像这样使用 ecmaFeatures.modules 来启用 ES6 模块支持

{
    ecmaFeatures: {
        modules: true
    }
}
{
    parserOptions: {
        sourceType: "module"
    }
}

此外,如果您在您的规则中使用 context.ecmaFeatures,那么您还需要通过以下方式更新您的代码

  1. 如果您正在使用 ES6 功能标志,例如 context.ecmaFeatures.blockBindings,请重写以检查 context.parserOptions.ecmaVersion > 5
  2. 如果您正在使用 context.ecmaFeatures.modules,请重写以检查 Program 节点的 sourceType 属性是否为 "module"
  3. 如果您正在使用非 ES6 功能标志,例如 context.ecmaFeatures.jsx,请重写以检查 context.parserOptions.ecmaFeatures.jsx

如果您的插件包含规则并且您正在使用 RuleTester,那么您还需要更新您为使用 ecmaFeatures 的规则传递的选项。例如

var ruleTester = new RuleTester();
ruleTester.run("no-var", rule, {
    valid: [
        {
            code: "let x;",
            parserOptions: { ecmaVersion: 6 }
        }
    ]
});

如果您在您的配置或您的自定义/插件规则和测试中没有使用 ecmaFeatures,则无需更改。

"eslint:recommended" 中的新规则

{
    "extends": "eslint:recommended"
}

在 2.0.0 版本中,以下 11 条规则被添加到 "eslint:recommended" 中。

解决方法:如果您不想收到这些规则的通知,您可以简单地禁用这些规则。

{
    "extends": "eslint:recommended",
    "rules": {
        "no-case-declarations": 0,
        "no-class-assign": 0,
        "no-const-assign": 0,
        "no-dupe-class-members": 0,
        "no-empty-pattern": 0,
        "no-new-symbol": 0,
        "no-self-assign": 0,
        "no-this-before-super": 0,
        "no-unexpected-multiline": 0,
        "no-unused-labels": 0,
        "constructor-super": 0
    }
}

作用域分析变更

我们发现了一些作用域分析中的 Bug,需要解决。具体来说,我们没有正确地考虑全局变量在所有定义方式中的情况。

最初,Variable 对象和 Reference 对象相互引用

  • Variable#references 属性是一个 Reference 对象数组,这些对象引用了该变量。
  • Reference#resolved 属性是一个被引用的 Variable 对象。

但在 1.x 版本之前,以下变量和引用在这些属性中具有错误的值(空)

  • 全局作用域中的 var 声明。
  • 全局作用域中的 function 声明。
  • 在配置文件中定义的变量。
  • /* global */ 注释中定义的变量。

现在,这些变量和引用在这些属性中具有正确的值。

Scope#through 属性具有 Reference#resolvednull 的引用。因此,作为此更改的结果,Scope#through 属性的值也发生了更改。

解决方法:如果您正在使用 Scope#through 来查找内置全局变量的引用,您需要进行以下几项更改。

例如,这是您在 1.x 版本中可能定位 window 全局变量的方式

var globalScope = context.getScope();
globalScope.through.forEach(function(reference) {
    if (reference.identifier.name === "window") {
        checkForWindow(reference);
    }
});

这是一种迂回的方式来查找变量,因为它是由 ESLint 事后添加的。window 变量位于 Scope#through 中,因为找不到定义。

在 2.0.0 版本中,window 不再位于 Scope#through 中,因为我们已经添加回了正确的声明。这意味着您可以直接引用 window 对象(或任何其他全局对象)。因此,之前的示例将更改为这样

var globalScope = context.getScope();
var variable = globalScope.set.get("window");
if (variable) {
    variable.references.forEach(checkForWindow);
}

进一步阅读:https://estools.github.io/escope/

使用 eslint:recommended 时的默认变更

如果您正在从 eslint:recommended 扩展,并且仅使用严重程度启用 no-multiple-empty-linesfunc-style,例如

{
    "extends": "eslint:recommended",
    "rules": {
        "no-multiple-empty-lines": 2,
        "func-style": 2
    }
}

规则 no-multiple-empty-lines 没有默认例外,但在 ESLint 1.x 中,应用了来自 eslint:recommended 的默认值,使得最多允许两个空行。

规则 func-style 的默认配置为 "expression",但在 ESLint 1.x 中,eslint:recommended 将其默认为 "declaration"

ESLint 2.0.0 移除了这些冲突的默认值,因此您可能会开始看到与这些规则相关的代码检查错误。

解决方法:如果您想保持之前的行为,请通过添加 {"max": 2} 来更新您的 no-multiple-empty-lines 配置,并将 func-style 更改为 "declaration"。例如

{
    "extends": "eslint:recommended",
    "rules": {
        "no-multiple-empty-lines": [2, {"max": 2}],
        "func-style": [2, "declaration"]
    }
}

SourceCode 构造函数 (Node API) 变更

SourceCode 构造函数可以处理 Unicode BOM。如果第一个参数 text 具有 BOM,则 SourceCode 构造函数会将 this.hasBOM 设置为 true,并从文本中移除 BOM。

var SourceCode = require("eslint").SourceCode;

var code = new SourceCode("\uFEFFvar foo = bar;", ast);

assert(code.hasBOM === true);
assert(code.text === "var foo = bar;");

因此,第二个参数 ast 也应该从移除 BOM 后的文本中解析。

解决方法:如果您在您的代码中使用 SourceCode 构造函数,请在移除 BOM 后解析源代码

var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options);
var sourceCode = new SourceCode(text, ast);

规则变更

  • strict - 默认为 "safe"(之前的默认值为 "function"

插件不再有默认配置

在 v2.0.0 之前,插件可以为插件指定 rulesConfigrulesConfig 会在有人使用该插件时自动应用,这与 ESLint 在其他所有情况下的行为相反(默认情况下什么都没有启用)。为了使插件行为保持一致,我们已移除对插件中 rulesConfig 的支持。

解决方法:如果您在您的配置文件中使用插件,您将需要在配置文件中手动启用插件规则。

更改语言