7.13.0发布:记录和图元,细化的编译器假设,以及顶级目标
我们刚刚发布了Babel 7.13.0,这是2021年的第一个次要版本
这个版本包括对@babel/core 的一些重要功能:一个可以在不同插件之间共享的targets 选项(类似于@babel/preset-env's one),一个可以精确调整配置以产生更小的编译输出的assumptions 选项,以及对使用本地ECMAScript模块编写的插件和预置的支持。
Babel现在支持转换Records和TuplesECMAScript提案,该提案为JavaScript带来了不可变的数据结构和结构平等,并支持解析Module Blocks提案。
此外,我们还增加了对一些新的Flow和TypeScript功能的支持。
你可以在GitHub上阅读完整的更新日志。
资助更新
我们已经加入了 "GitHub组织的赞助商 "计划,所以你现在可以直接通过GitHub赞助我们😊。
这些资金将用于支持我们的团队(目前有一名全职和三名兼职维护者)继续努力提高稳定性和开发新功能。
我们的捐款和支出都会通过我们的开放集体页面公开追踪,在这里我们也会追踪来自GitHub赞助商的捐款。
我们欢迎来自个人和公司的捐赠。如果你的公司有兴趣成为黄金级别的赞助商(1千美元/月),并希望讨论更多,请联系team@babeljs.io!
亮点
顶级的targets 选项(#12189,RFC)
@babel/preset-env targets 选项允许用户指定他们的目标环境,自动选择要转换的语法和要注入的polyfills。自从发布了 ,我们了解到插件@babel/preset-env本身也可以从了解你的目标中受益。目前,这可能有点麻烦,因为你必须指定你的目标两次(例如,如果你正在使用我们新的polyfill插件)。通过引入 作为顶级选项,你现在只需要指定一次你的目标。targets
| 旧配置 | 新配置 |
|---|---|
{
"presets": [
["@babel/preset-env", {
"targets": ">1%, not ie 11"
}]
],
"plugins": [
["polyfill-es-shims", {
"targets": ">1%, not ie 11"
}]
]
}
|
{
"targets": ">1%, not ie 11",
"presets": ["@babel/preset-env"],
"plugins": ["polyfill-es-shims"]
}
|
我们建议将您的Babel配置转换为使用新的顶级targets 选项,因为它有以下额外的好处。
- 它能更好地处理
esmodules: true目标。(它与其他目标相交,而不是取代它们) - 随着我们在插件中引入更多与
targets有关的支持,您将自动从更优化的输出中受益
你可以在其RFC中阅读关于这个新选项的细节。
🔮 未来我们可能会探索将
@babel/preset-env移到@babel/core,这样你就不必再安装一个额外的软件包来开始使用Babel。这个新选项可以看作是朝这个方向迈出的第一步。
顶层assumptions 选项
我们的许多插件都有一个loose 选项,它告诉Babel通过对您的代码进行某些假设并忽略JavaScript规范中的某些边缘情况来生成更小/更快的输出。
然而,loose 有一些问题,导致用户的困惑:这个术语本身无助于描述它究竟如何影响编译器的行为,更糟糕的是,有时需要为多个插件设置配置,以确保一切都能编译。
为了帮助解决这些问题,我们增加了一个新的顶层选项,告诉Babel它可以对你的代码做哪些假设。assumptions!与新的targets 选项类似,现在每个插件都会收到你所启用的假设,不需要再单独设置该选项。这真的很有价值,因为一个插件可以受到多个假设的影响,而一个假设可以影响多个插件。
⚠️这是高级功能。和之前的
loose选项一样,在启用假设时请小心,因为它们不符合规范,可能会以意想不到的方式破坏你的代码。
例如,在转换类的时候,Babel会默认生成这个输出。
| 输入 | 输出 |
|---|---|
class Test {
constructor() {
this.x = 2;
}
}
// You can test the thrown error in the console:
// Uncaught TypeError: class constructors must be invoked with 'new'
Test();
|
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
let Test = function Test() {
_classCallCheck(this, Test);
this.x = 2;
};
// You can test the thrown error in the console:
// Uncaught TypeError: class constructors must be invoked with 'new'
Test();
|
然而,启用noClassCalls 假设告诉 Babel "我从不尝试调用没有new 的类,所以你可以不用担心它的编译"。
{
"targets": "firefox 30",
"assumptions": { "noClassCalls": true },
"presets": ["@babel/preset-env"]
}
| 输入 | 输出 |
|---|---|
class Test {
constructor() {
this.x = 2;
}
}
// Won't throw since we violated the assumption
Test();
|
let Test = function Test() {
this.x = 2;
};
// Won't throw since we violated the assumption
Test();
|
在我们的文档中查看假设的完整列表,你可以单独启用或禁用它们,看看它们如何影响编译后的输出。
记录和图元支持
由于与彭博社的合作,Babel现在支持转换"记录和图元 "第二阶段的建议。
Babel插件使用全局Record 和Tuple 函数对记录和图元的语法进行转换。
| 输入 | 输出 |
|---|---|
let data = #{
name: "Babel",
ids: #[1, 2, 3]
};
|
let data = Record({
name: "Babel",
ids: Tuple(1, 2, 3),
});
|
这意味着你需要为这些全局函数加载一个polyfill,比如说 @bloomberg/record-tuple-polyfill,要么通过在你的代码中导入它,要么用<script> 标签。
<script src="https://unpkg.com/@bloomberg/record-tuple-polyfill@0.0.3/lib/index.umd.js" />
注意:目前没有引擎支持记录和图元,所以你总是需要加载polyfill。
为了启用这种转换,你需要在你的配置中添加@babel/plugin-proposal-record-and-tuple 。
新的Flow功能
Babel 7.13.0支持两个新的Flow功能。
-
this函数中的类型注解,允许你指定 对象的类型,就像它是一个参数一样。thisfunction getPerson(this: Database, id: string): Person { this instanceof Database; // true } -
enum带有未知成员的声明enum PetKind { Dog, Cat, Snake, ... }
支持TypeScript 4.2
TypeScript 4.2支持一些新的语法特征,如抽象构造函数签名。
你可以在TypeScript发布的帖子中阅读更多关于这些变化。
@babel/runtime 中的自动 ES 模块
@babel/runtime 包含了CommonJS和ECMAScript模块格式的所有Babel运行时辅助工具。
到目前为止,你必须手动选择你想使用的模块,指定@babel/plugin-transform-runtime 的useESModules 选项。
我们现在已经重新组织了@babel/runtime 的内部结构,利用Node.js支持的新的 "exports"package.json 字段支持的Node.js和捆绑器,因此它们能够在CJS和ESM之间自动选择。
由于这个原因,useESModules 选项现在已被废弃,并将在Babel 8中被删除。