跳至主要内容

Babel 路线图

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

这远非我们为 Babel 带来的所有新功能或重要更改的完整列表,但如果您对项目的发展方向感兴趣,这是一个很好的总结。我们实际上可能无法完成所有列出的要点,或者可能将其中一些推迟到明年。其中一些有明确的起点和终点,而另一些则需要更多研究或 RFC

如果您的公司有兴趣并希望直接赞助任何特定项目,请 联系我们

Babel 2021 路线图

Babel 8

我们已经讨论 Babel 8 版本一年多了(我们最初计划在大约一年前发布)!但是,我们现在比以往任何时候都更接近发布!

大多数剩余任务都在 跟踪问题 中,但仍然有一些障碍

  • 我们希望放弃对 Node.js 10 的支持,它将在 2021-04-30 停止维护。
  • 我们希望将 Babel 作为一个纯 ESM 包发布。我们现在正在将我们的源代码转换为与 Node.js 的 ESM 实现兼容,并且在这样做的同时,我们正在研究如何让当前使用 Babel 将 ESM 编译为 CJS 的人更容易。
  • 我们正在尝试将我们的 TypeScript AST 与 typescript-eslint 项目保持一致。我们的 AST 几乎相同,但我们需要引入一些小的破坏性更改才能完全对齐。
  • 我们的发布基础设施尚不支持预发布版本,也不支持使用多个“主”分支(一个用于 Babel 8,一个用于 Babel 7)。
  • 我们还没有确定 Babel 7 维护策略。

实施新的 TC39 提案

Babel 目前可以解析所有 Stage 3 提案,除了顶级 await、导入断言和 JSON 模块(最好由处理依赖关系图的打包器处理)之外,我们都可以转换所有提案。

我们支持所有 Stage 2 提案,除了

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

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

虽然我们不支持许多 Stage 1 提案,但最近对管道运算符和 do 表达式进行了更新。由于我们已经支持这些提案并且社区对此感到非常兴奋,因此我们将更新我们的实现。

还有一些其他提案(例如模式匹配)我们尚未实现,因为他们的拥护者希望对语法和语义进行重大更改。但是,我们正在密切关注他们的发展,并将在它们稳定后立即在 Babel 中实现它们。

@babel/preset-env 移至 @babel/core

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

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

@babel/preset-env 直接移至 @babel/core 有两个很大的优势

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

已经有 一个 RFC 将稳定的 ECMAScript 功能的插件移至 @babel/core,这是朝这个方向迈出的第一步。

使用我们当前的 @babel/preset-env 架构,我们需要专门处理官方插件,以根据 targets 自动启用或禁用它们。但是,这有两个缺点

  • 特定插件的兼容性数据与插件实现完全分开(它甚至不是依赖项,更像是内部隐式对等依赖项:插件 -> @babel/core -> @babel/compat-data);
  • 官方插件将从 @babel/core 获得特殊待遇,但我们希望确保第三方插件具有与官方插件相同的功能。

继续开发 babel-polyfills 项目

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

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

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

无论我们采用哪种方式,当用户需要更新其配置中的 core-js 集成时,我们都希望至少为他们提供一种替代方案。 core-js 是一个非常好的 polyfill,可以确保尽可能高的规范合规性,但用户可能更喜欢不同的权衡。

(Nicolò) 正在与 @ljharb 合作,以确保 @es-shims 项目 至少支持所有 ES2015+ 功能(我们实际上目标是 ES5+),以便 Babel 用户可以自由选择至少两种选择。

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

扩展 targets 的使用以进行精细转换

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

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

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

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

为每个功能创建一个插件是次优的。例如,我们可以将私有方法转换为私有字段,然后,如果需要,将它们转换为旧语法。但是,如果我们知道需要向下转换,我们可以通过直接将私有方法转换为旧语法而无需中间步骤来生成更好/优化的输出。

从 Babel 7.13.0 开始,我们可以在插件内部直接读取 targets 选项,我们可以修改我们的插件以自动执行给定 ECMAScript 功能的部分编译,这将在输出大小和运行时性能方面提供优势。

现有技术

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

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

行动要点

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

  • 我们需要通过收集现实世界的 browserslist 查询并通过模拟流行查询(例如,defaults>2%, not dead)在未来的演变方式来确定哪里可以使用这些优化。
  • 我们需要实际实现必要的优化,确保它们仍然可以与其他插件一起正常工作(因为它们会大大增加可能的转换组合的数量)。

研究新的编译器 assumptions

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

但是,我们只包含了在 loose 模式下编译时已经做出的假设的选项。我们现在可以调查我们的用户可能需要哪些新的假设。

已经有一些提案,例如

  • #8222 - 假设所有 ESM 导入实际上都是不可变的,避免了实时绑定所需的代码。
  • #11356 - 假设编译后的类不会继承原生类,避免了实例化可能是原生类的运行时性能成本。

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

  • 手动检查哪些功能会被编译成“不明显”的输出,这通常是由许多开发人员不关心的边缘情况造成的。
  • 征求社区的反馈,因为开发人员可以在他们的应用程序上测试哪些假设有效,哪些无效。

彻底检查 Babel REPL

Babel REPL 是一个方便的游乐场,可以学习 Babel 如何转换源代码。

当前限制

有用的功能

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

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

教育/调试工具

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

Henry一直在断断续续地进行一些工作

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

有关我们正在考虑的交互式示例:https://babel-explorer.netlify.app/(在底部区域单击并按住鼠标!)