Skip to main content

Babel 路线图

本文档概述了我们的团队成员希望在今年进行的一些改进。

🌐 This document outlines some of the improvements our team members would like to work on during this year.

这远不是我们将带给 Babel 的所有新功能或重要变化的完整列表,但如果你对项目的发展方向感兴趣,这是一个不错的概览。我们可能无法完成列表中的每一项,或者会将其中一些推迟到明年。有些功能有明确的起止点,而有些则需要更多的研究或RFCs支持。

🌐 This is far from being a complete list of all the new features or important changes that we'll bring to Babel, but it's a good summary if you are interested in the general direction that the project is moving toward. We may not actually finish every listed point or may delay some of them to the next year. Some of them have clear starting and ending points, while others need more research or RFCs.

如果贵公司有兴趣,并想直接赞助任何特定项目,请 联系 我们!

🌐 If your company is interested and would like to directly sponsor any particular item please reach out!

Babel 2021 路线图​

🌐 Babel 2021 Roadmap

Babel 8​

我们已经讨论 Babel 8 的发布超过一年了(我们最初大约一年前就计划好了)!不过,现在我们比以往任何时候都更接近发布了!

🌐 We have been talking about the Babel 8 release for more than one year (we initially scheduled it about one year ago)! However, we are now closer then ever to its release!

剩下的大部分任务都在跟踪问题里,但还是有一些阻碍:

🌐 Most of the remaining tasks are in the tracking issue, but there are still a few blockers:

  • 我们想要停止对 Node.js 10 的支持,它在 2021-04-30 停止维护。
  • 我们想把 Babel 发布为一个纯 ESM 包。我们现在正在将源码转换为兼容 Node.js 的 ESM 实现,同时我们也在考虑如何让目前使用 Babel 将 ESM 编译为 CJS 的人更方便。
  • 我们正在尝试让我们的 TypeScript AST 与 typescript-eslint 项目保持一致。我们的 AST 几乎完全相同,但我们需要引入一些小的破坏性更改才能完全对齐。
  • 我们的发布基础设施还不支持预发布,也不支持使用多个“main”分支(一个用于 Babel 8,一个用于 Babel 7)。
  • 我们还没有想出 Babel 7 维护的政策。

实现新的 TC39 提案​

🌐 Implement new TC39 proposals

Babel 目前可以解析所有 Stage 3 提案,我们可以转换所有这些提案,除了顶层 await、导入断言和 JSON 模块(最好由使用依赖图的打包程序处理)。

🌐 Babel can currently parse all the Stage 3 proposals, and we can transform all of them except for top-level await, import assertions and JSON modules (which are best handled by bundlers working with the dependencies graph).

我们支持所有第 2 阶段的提案,除了:

🌐 We support all the Stage 2 proposals except for:

  • 装饰器提案的新迭代(我们需要同时实现解析和转换);
  • 模块块提案的转换(我们在 Babel 7.13.0 中实现了解析)。

我们将实现对装饰器的支持,并研究是否以及如何实现模块块的转换。

🌐 We will implement support for decorators, and investigate if and how we can implement a transform for module blocks.

虽然我们不支持很多阶段 1 的提案,但最近对管道操作符和 do 表达式有了一些更新。因为我们已经支持这些提案,并且社区对此非常兴奋,所以我们会更新我们的实现。

🌐 While we don't support many Stage 1 proposals, there have been recent updates to the pipeline operator and to do expressions. Since we already support those proposals and the community is quite excited about them, we will update our implementations.

还有其他一些提案(比如模式匹配)我们还没有实现,因为它们的支持者预计会对语法和语义做出重大修改。不过,我们一直在密切关注它们的发展,并会在它们稍微稳定后尽快在 Babel 中实现。

🌐 There are also other proposals (such as pattern matching) that we have not yet implemented because their champions expect to do significant changes to the syntax and semantics. However, we are closely following their development, and will implement them in Babel as soon as they stabilize a bit.

把 @babel/preset-env 移到 @babel/core​

🌐 Move @babel/preset-env into @babel/core

一个最小的 Babel 转换设置至少需要三个包:

🌐 A minimal Babel transforming setup requires at least three packages:

  • @babel/core
  • @babel/preset-env
  • 一个 Babel “运行器”(@babel/cli、babel-loader、@rollup/plugin-babel 等)

直接把 @babel/preset-env 移到 @babel/core 有两个大好处:

🌐 Moving @babel/preset-env directly into @babel/core has two big advantages:

  • 在简单的项目中配置 Babel 会更容易,你只需要在 babel.config.json 中启用一个 compileJS: true 选项(或者未来甚至可能成为默认设置——它不能成为默认,因为 @babel/eslint-parser 不会编译源代码)
  • 它会确保插件版本与 @babel/core 版本保持同步,避免大多数由版本不匹配或不兼容的软件包引起的错误
  • 当我们迁移到 ESM 时,在 transformSync 中同步解析和加载插件会很困难。这也防止了它成为一个问题。

已经有一个 RFC 提议把 @babel/core 中稳定的 ECMAScript 特性插件移动,这也算是朝这个方向迈出的第一步。

🌐 There is already a RFC to move plugins for stable ECMAScript features in @babel/core, which is the first step in this direction.

用我们目前的 @babel/preset-env 架构,我们需要特别处理官方插件,以便根据 targets 自动启用或禁用它们。不过,这有两个缺点:

🌐 With our current @babel/preset-env architecture, we would need to specially handle official plugins to automatically enable or disable them based on targets. However, this has two drawbacks:

  • 特定插件的兼容性数据与插件实现完全分离(它甚至不是依赖,更像是内部隐式对等依赖:plugin -> @babel/core -> @babel/compat-data);
  • 官方插件会从 @babel/core 那里获得特别待遇,但我们想确保第三方插件也有和官方插件一样的能力。

继续开发 babel-polyfills 项目​

🌐 Continue developing the babel-polyfills project

我们已经决定在 Babel 8 中移除旧的 core-js@2 对 @babel/preset-env 的支持。我们也想停止推广某个特定的第三方 polyfill,因为这可能会让用户觉得它是 Babel 本身的一部分。

🌐 We have already decided to remove the older core-js@2 support from @babel/preset-env in Babel 8. We also want to stop promoting a specific third-party polyfill, which might give our users the impression that it's part of Babel itself.

这可能以两种不同的方式发生:

🌐 This might happen in two different ways:

  • 我们在 Babel 8 中只是从 @babel/preset-env 移除了 core-js@3,鼓励用户迁移到 babel-plugin-polyfill-corejs3(从 7.10.0 版本开始,这就是 @babel/preset-env 内部使用的东西)
  • 我们可以在 @babel/preset-env 中保留 core-js@3 的支持,但在我们迁移转换插件时不会把它移到 @babel/core。

无论我们选择哪条路线,我们都希望在用户需要更新其配置中的 core-js 集成时,至少提供一个替代方案。core-js 是一个非常不错的 polyfill,可以确保尽可能高的规范兼容性,但用户可能会更喜欢不同的权衡。

🌐 Whichever path we take, we would like to offer at least one alternative to our users when they'll need to update the core-js integration in their configuration. core-js is a really good polyfill that ensures the highest possible spec compliancy, but users may prefer different trade-offs.

(Nicolò) 正在和 @ljharb 合作,以确保 @es-shims 项目 至少支持所有 ES2015+ 特性(实际上我们的目标是 ES5+),这样 Babel 用户就可以在至少两个选项之间自由选择。

这需要在放弃对 core-js@3 的内置支持之前发生,这样对 es-shims 感兴趣的人就不必迁移两次。

🌐 This needs to happen before dropping built-in support for core-js@3, so that people interested in es-shims don't have to migrate twice.

扩展 targets 用于细粒度转换的使用​

🌐 Expand targets usage for granular transforms

从一开始,@babel/preset-env 就使用 targets 选项来自动启用或禁用转换插件。

🌐 Since the beginning, @babel/preset-env has used the targets option to automatically enable or disable transform plugins.

但是,Babel 插件和浏览器中实现的功能之间并没有一对一的映射。

🌐 However, there isn't a 1-to-1 mapping between Babel plugins and features implemented in browsers.

例如,我们为不同的类字段类型(公共和私有、静态和实例)提供了一个插件,但浏览器有不同的兼容性矩阵:

🌐 For example, we have a single plugin for the different class fields types (public and private, static and instance), but browsers have varying compatibility matrices:

  • Firefox 73 和 Safari 14 仅支持公共实例字段
  • Firefox 75+ 支持公共实例和静态字段
  • Chrome 79+ 支持公共和私有字段,但不支持某些可选链接表达式中的私有字段
  • Chrome 84+ 完全支持私有字段,也支持私有方法
  • Safari TP 121 完全支持私有字段(即使是 ?.),但不支持私有方法

为每个功能创建一个插件并不是最优的。例如,我们可以把私有方法转换成私有字段,然后如果需要,再把它们转换回旧语法。然而,如果我们知道最终需要降级转换,我们可以直接把私有方法转换成旧语法,而不经过中间步骤,这样可以生成更好/优化的输出。

🌐 Creating a plugin for each feature is sub-optimal. For example, we can convert private methods to private fields and then, if needed, convert them to older syntax. However, we can generate better/optimized output by directly converting private methods down to older syntax without the intermediate step if we know that it needs to be transpiled down.

自从 Babel 7.13.0 起,我们可以在插件内部直接读取 targets 选项,我们可以修改插件来自动对某个 ECMAScript 特性进行部分编译,这样可以在输出大小和运行时性能上带来优势。

🌐 Since Babel 7.13.0, we can read the targets option directly inside a plugin, we can modify our plugins to automatically perform a partial compilation of a given ECMAScript feature, which would give advantages in the output size and runtime performance.

现有技术

这种方法并不完全是新的。多亏了与@_developit 的合作,在 Babel 7.9.0 中,我们为 @babel/preset-env 引入了一个新的 bugfixes: true 选项。当启用此选项,并且使用 esmodules: true 作为编译目标时,我们只会部分编译 一些功能。这最初让我们考虑了这种可能性,但在使用更现代的目标(例如 defaults, not ie 11)时,目前的部分转换就没那么有用了。

🌐 This approach isn't completely new. Thanks to a collaboration with @_developit, in Babel 7.9.0 we introduced a new bugfixes: true option for @babel/preset-env. When this option is enabled, and when using esmodules: true as the compilation target, we only partially compile some features. This what made us initially think about this possibility, but the current partial transforms are less useful when using more modern targets (for example, defaults, not ie 11).

我们也已经使用 targets 选项来决定在编译对象展开时是否可以使用 Object.assign。

🌐 We also already use the targets option to decide whether we can use Object.assign when compiling object spread or not.

行动点

这个目标可以分为两个可以并行完成的大任务:

🌐 This goal can be split into two big tasks that can be done in parallel:

  • 我们需要通过收集真实的 browserslist 查询,以及模拟热门查询(例如 defaults 或 >2%, not dead)未来的发展,来确定这些优化可以发挥作用的地方。
  • 我们需要实际实现必要的优化,确保它们仍然可以与其他插件一起正常工作(因为它们会大大增加可能的转换组合的数量)。

研究新的编译器 assumptions​

🌐 Investigate new compiler assumptions

在 Babel 7.13.0 中,我们引入了一个新的顶层 assumptions 选项,用来正式化 loose 模式选项的功能,并为用户提供更细粒度的控制(因为他们通常只能启用某些假设,而不能全部启用)。

🌐 In Babel 7.13.0 we introduced a new top-level assumptions option, to formalize what the loose mode option does and offer more granular control to our users (since often they can only enable some assumptions and not all of them).

不过,我们只包括了在以 loose 模式编译时我们已经做过的假设选项。现在我们可以看看用户可能需要哪些新的假设了。

🌐 However, we only included options for assumptions we already made when compiling in loose mode. We can now investigate what new assumptions our users might need.

已经有一些建议,例如:

🌐 There are already some proposals, such as:

  • #8222 - 假设所有的 ESM 导入实际上都是不可变的,从而避免为实时绑定编写代码。
  • #11356 - 假设已编译的类不继承本地类,从而避免实例化可能的本地类所需的运行时性能开销。

我们可以通过以下方式找到我们应该实现的新假设:

🌐 We can find which new assumptions we should implement, by:

  • 手动检查我们编译成“非显而易见”输出的功能,这通常是由很多开发者不在意的边缘情况引起的。
  • 征求社区的反馈,因为开发者可以测试哪些假设在他们的应用上有效,哪些无效。

彻底改造 Babel REPL​

🌐 Overhaul the Babel REPL

Babel REPL 是学习 Babel 如何转译源代码的便捷在线运行。

🌐 The Babel REPL is a convenient playground to learn how Babel transpiles source code.

当前限制:

🌐 Current limits:

好有特点:

🌐 Features good to have:

  • AST Explorer(与现有的集成)
  • 具有完整堆栈跟踪的 stderr 作为错误日志
  • 标准输出作为输出
  • 从 UI 更改 Babel 版本

在 babel-website 中,至少 15% 的未解决问题与 REPL 有关:https://github.com/babel/website/issues?q=is%3Aissue+is%3Aopen+label%3Arepl

🌐 At least 15% of open issues in babel-website are related to the REPL: https://github.com/babel/website/issues?q=is%3Aissue+is%3Aopen+label%3Arepl

教育/调试工具​

🌐 Educational/Debugging Tooling

关于 REPL/ASTExplorer,我们可以增加更多的工具来帮助我们自己和第三方插件的通用插件开发。这本质上是探索性的:不同的 AST 可视化、调试等等。

🌐 Related to the REPL/ASTExplorer, we could do with more tooling to help with general plugin development for ourselves and 3rd-party plugins. This is rather exploratory in nature: different visualizations for the AST itself, debugging, etc.

亨利一直在进行中的一些事情:

🌐 Some things already in progress Henry has been working on and off on:

  • Codesandbox 用于制作一个简单的 Babel 插件,类似于 https://astexplorer.net,但带有自定义配置。
  • 可视化 输入到输出的映射,帮助理解 Babel 是如何转换代码的。即使是用于文档,让 JavaScript 用户熟悉新语法或特定转换的演示,也可能很有用。
  • 映射 就像源映射类型的结构一样,将输入映射到输出。可以做反向映射,找出哪个插件导致代码以某种方式输出,这对调试很有帮助。

想看看我们在想什么的互动示例吗: https://babel-explorer.netlify.app/ (在底部区域点击并按住鼠标!)

🌐 For an interactive example of what we are thinking about: https://babel-explorer.netlify.app/ (click and hold the mouse in the bottom sector!)