下一步ESLint将带来什么

原文信息: 查看原文查看原文

What's coming next for ESLint

- Nicholas C. Zakas

新的配置系统只是即将到来的ESLint重大变化的开始。

当我们在4月发布了ESLint v9.0.0,这是30个月以来的第一个重大版本,并正式引入了新的配置系统。ESLint v9.0.0还进行了一些规则API更改,为接下来的变化做准备。发布之后,我们花了很多时间创建兼容性工具,一个配置迁移工具,以及一个规则API转换工具来帮助生态系统迁移到ESLint v9.0.0。所有这些工作都是我们继续进行ESLint下一个重大变化所必需的。

语言插件

两年前,TSC决定开放ESLint,使其能够检查除JavaScript以外的其他语言。实际上,ESLint核心做的很多事情并不特定于JavaScript:查找和读取文件、加载文件特定配置、收集规则违规、将结果输出到控制台等。此外,我们不断发现插件在ESLint内部检查其他语言(如GraphQLHTML),通过相同的逻辑传递不同的AST,这是低效和容易出错的,必须有更好的方法。

2023年,语言插件RFC正式获得批准。然而,要实现这个RFC,我们需要正式发货新的配置并进行一些规则API更改。特别是,规则API更改是必要的,以分离ESLint核心正在做的事情和语言插件将为自定义规则提供什么。一旦这两个更改可用,我们开始艰巨的任务,重构ESLint核心,从语言中立的部分提取出特定于JavaScript的部分。

以下是接下来可以期待的事情(没有具体的时间表,因为一切都取决于贡献者的可用性):

  • @eslint/js - 我们将逐步将所有与JavaScript相关的功能移入@eslint/js包中,包括规则和文档。我们将重用现有的Espree仓库,将其转换为包含Espree、eslint-scopeeslint-visitor-keys和所有核心JavaScript规则的monorepo。这将使我们能够在一个仓库中处理所有与JavaScript相关的事情。
  • @eslint/json - 我们的第一个语言插件将允许ESLint原生地检查JSON文件。这个插件将包含解析逻辑和所有相关的规则和文档。与@eslint/js类似,这将使我们能够专注于JSON检查的单一仓库,进一步将任何语言特定功能从核心中移出。
  • @eslint/markdown - eslint-plugin-markdown将被重命名为@eslint/markdown,以更好地与其他包对齐。我们将添加检查Markdown和Markdown特定规则的能力。

目前的计划是拥有这三个官方ESLint语言插件,并希望它们能作为生态系统开发更多语言插件的示例。

将语言特定功能提取到单独的仓库后,剩下的任务就是完全重写核心。

核心重写

ESLint仓库中的代码架构自ESLint首次创建11年以来并没有显著变化。因此,积累了大量的技术债务,阻碍了我们进行一些我们想要进行的更改。我们目前面临的一些问题:

  • 同步核心逻辑。 Linter类是完全同步的,这意味着我们无法支持异步规则或异步解析,这是我们经常收到的两个功能请求。我们需要添加一个工作异步的第二个类,或者向Linter添加异步工作的方法。两种选择看起来都是大量的工作,实际上是重写核心的大部分。
  • 有限的API。 公共API是有限的,因为ESLint最初并没有想到会被用作API。最初的linter对象仅用于启用浏览器演示。后来被Linter类取代,再后来,为了完全模仿命令行界面,又添加了ESLint类。当我们想要公开新功能时,它需要存在于这两个听起来相似的API中的一个,不幸的是,主要的决策点是API是否需要在浏览器中可用。如果是,那么它需要在Linter中,否则它需要在ESLint中。这既令人困惑,从长远来看也不可持续。
  • 缺乏类型检查。 我们一直希望向仓库中添加类型检查以帮助捕捉潜在问题,但过去的尝试需要大量的工作和协调。最终,我们得出结论,这不值得努力。
  • 停留在CommonJS中。 类似于类型检查的情况,虽然有将代码库转换为ESM的愿望,但这样做所需的工作量令人望而却步。我们将花费大量时间进行转换,最终只得到一个等价的功能集。

在考虑是继续逐步更改现有核心还是从头开始的选项后,我们决定是时候从头开始了。虽然我们坚信完全重写代表着重大风险,但经过11年,我们可以诚实地说,我们已经从最初的架构中得到了最多。

以下是接下来可以期待的:

  • 一个新的仓库。 eslint/rewrite仓库是我们语言中立工作的新家。它是一个monorepo,我们将在这里管理所有直接以某种方式与核心相关的包。
  • 现代包。 eslint/rewrite中的每个包都将达到现代标准,发布ESM入口点以及类型定义。如果可能,我们还将发布CommonJS入口点。所有包都带有可证明性,同时发布到npm和JSR(如果适用)。
  • 运行时不可知的核心。 @eslint/core包将包含一个运行时不可知的ESLint API以及核心类型定义。我们将随着设计新API的进行,逐步构建这个包,从eslint包中提取功能片段。随着每年出现更多的JavaScript运行时,我们认为运行时不可知的核心变得越来越重要。
  • 可组合的API。 与将所有功能捆绑到一个或两个类不同,新的API将是可组合的,有许多专门设计的类旨在一起使用。类将遵循单一责任原则,使更改更容易,并在集成中自定义ESLint。
  • 一个新的CLI。 我们将在@eslint/node包中从头开始重写CLI。我们将从最常见的用例开始,并重新评估每个标志,以确保它仍然适用于语言中立的核心。使用不同的包名允许我们尝试新的CLI,而不会干扰eslint包的使用。此包还将导出额外的Node.js特定API。
  • 并行开发。 我们将继续并行维护eslint和重写,这样我们就不会为了一个全新的东西牺牲现有包。目标是让eslint包慢慢变小,并使用@eslint/core中包含的API,以便我们尽可能限制重复。

结论

我们对ESLint未来的这个方向非常兴奋,因为我们认为这代表了ESLint演变的下一个逻辑步骤。将ESLint转变为任何人都可以为其编写插件的语言中立的linter将简化开发,通过减少任何项目所需的linting工具和编辑器扩展的数量。此外,将我们的核心重写为更可组合的API允许更简单、更可定制的集成,同时拥有我们自己的类型定义,以确保与API的兼容性。

ESLint已经用其当前架构度过了11年,我们希望这些变化将帮助我们度过接下来的11年。

分享于 2024-07-16

访问量 33

预览图片