ESLint的新配置系统第三部分:开发者预览

372 阅读4分钟

在我之前的文章中,我解释了使用新的 "扁平 "配置系统的基本概念。在我们做更多的内部测试时,新的配置系统还没有与CLI绑定,但我们确实想给ESLint社区一个机会,在我们努力将其纳入CLI时,尝试使用扁平配置。所以ESLint v8.21.0包含了几种方法,在我们的工作中尝试平面配置。请记住,这篇文章中提到的所有内容都是实验性的,我们希望在你尝试时得到你的反馈。

Linter 类中使用平面配置

如果你目前正在使用eslint 包中的Linter ,你可以通过在构造函数中设置configType: "flat" 作为一个选项来启用平面配置。这里有一个例子:

const linter = new Linter({ configType: "flat" });

const messages = linter.verify("new Map()", {
    languageOptions: {
        ecmaVersion: 5,
        sourceType: "script"
    },
    rules: {
        "no-undef": "error"
    }
}, "filename.js");

当你把configType: "flat" 作为一个选项时,Linter 希望传递给verify() 的任何配置对象都是 flat config 格式的。在这个例子中,verify() 的第二个参数是一个平面配置对象(你可以传递单个对象或一个对象数组)。对verify() 的任何调用都会假定被提示的文本是一个文件名以.js 结尾的JavaScript文件,但在第三个参数中传递一个明确的文件名总是一个好主意。

无论你使用哪种配置系统,这个基本情况都是一样的,但有一些重要的区别:

  • defineRule(),defineRules(), 和defineParser() 现在抛出错误。运行时插件(在我之前的文章中讨论过)使这些方法变得过时。
  • getRules() 也会抛出一个错误。这个方法会根据它被调用的时间返回不同的数据,所以它不能和flat config一起使用。

ESLint 类中使用flat config

在实现flat config的过程中,我们发现创建一个选项来切换配置系统是非常困难的,就像我们为Linter 。相反,我们创建了一个FlatESLint 类,它封装了ESLint 中的所有现有功能,但使用 flat config 而不是 eslintrc。FlatESLint 类只是作为一个功能预览;一旦我们永久地切换到flat config,当前的ESLint 类将被删除,FlatESLint 将被重命名为ESLint

现在,你可以通过use-at-your-own-risk 入口访问FlatESLint ,就像这样:

// ESM
import pkg from "eslint/use-at-your-own-risk";
const { FlatESLint } = pkg;

// CommonJS
const { FlatESLint } = require("eslint/use-at-your-own-risk");

之后,你可以以与ESLint 相同的方式使用FlatESLint ,如:

const eslint = new FlatESLint({
    cwd: originalDir,
    overrideConfigFile: "other.config.js"
});
const results = await eslint.lintText("foo");

Linter 一样,FlatESLintESLint 之间也有一些值得指出的区别:

  1. 缓存尚未在FlatESLint 中实现,所以cache: true 会抛出一个错误。
  2. useEslintrc 选项已被删除。如果你想避免自动加载eslint.config.js 而不指定另一个配置文件,请设置overrideConfigFile: true
  3. envs 选项已被删除。
  4. resolvePluginsRelativeTo 选项已被删除。
  5. rulePaths 选项已被删除。自定义规则必须由 config 直接添加。

用平面配置和RuleTester 类测试规则

ESLint 类类似,没有简单的方法来提供一个在 eslintrc 和 flat config 之间切换的选项,所以我们创建了一个单独的FlatRuleTester 类。同样类似于ESLintFlatRuleTester 类是临时的,一旦我们完全切换到flat config,它将最终被改名为RuleTester 。你可以像这样访问FlatRuleTester

// ESM
import pkg from "eslint/use-at-your-own-risk";
const { FlatRuleTester } = pkg;

// CommonJS
const { FlatRuleTester } = require("eslint/use-at-your-own-risk");

任何你可以在RuleTester 中指定eslintrc配置的地方,都需要在FlatRuleTester 中成为一个平面配置。 这里有一些例子。

const ruleTester = new FlatRuleTester({
    languageOptions: {
        ecmaVersion: 5,
        sourceType: "script"
    }
});

ruleTester.setDefaultConfig({
    languageOptions: {
        ecmaVersion: 5,
        sourceType: "script"
    }
});

在单个测试中,你可以在每个测试中直接使用languageOptions

ruleTester.run("my-rule", rule, {
    valid: [
        {
            code: "var test = 'foo'",
            languageOptions: {
                sourceType: "script"
            }
        },
        {
            code: "var test2 = 'bar'",
            languageOptions: {
                globals: { test: true }
            }
        }
    ],
    invalid: [
        {
            code: "bar",
            languageOptions: {
                sourceType: "script"
            },
            errors: 1
        }
    ]
});

在使用FlatRuleTester 时需要注意的一些事情:

  1. 默认的ecmaVersion 现在是"latest" ,所以如果你没有在你的测试中指定ecmaVersion ,可能会有一个不兼容,因为eslintrc的默认ecmaVersion5
  2. 默认的sourceType 现在是"module" ,所以如果你没有在测试中指定sourceType ,可能会出现不兼容的情况,因为eslintrc的默认sourceType"script" 。这主要表现在处理全局范围的变量上。

总结

我们认为新的配置系统对ESLint用户来说将是一个很好的体验,但为了实现这一点,我们必须确保ESLint的生态系统为这些变化做好准备。这就是为什么我们把这个开发者预览放在一起,让我们所有的插件、自定义规则、分析器和可共享配置的作者提前看看他们的包将如何在新的配置系统中工作。这是你给我们提供反馈的机会,并帮助解决任何与平面配置不兼容的问题。

我们感谢你的帮助和反馈!