7.5.0发布:动态导入和F#管道
今天我们发布了Babel 7.5.0!
这个版本包括对几个ECMAScript提案的改进支持:Stage 1管道操作员的F#变体和Stage 4动态import() 提案的官方插件(同时支持preset-env )。它还支持TypeScriptnamespaces(实验性)和Browserslist的default 查询,在preset-env 。
你可以在GitHub上阅读整个更新日志。
感谢Wesley Wolfe、Martin Zlámal、Blaine Bublitz、Letladi Sebesho、Paul Comanici、Lidor Avitan、Artem Butusov、Sebastian Johansson和Min ho Kim的第一次PR
我们一直在寻找帮助,特别是在分流问题、审查拉动请求和在Slack上帮助人们。我们正在尝试使用GitHub实施的新的分流角色,我们希望表彰社区中那些愿意站出来帮助我们的人!😉
巴别组织的最新成员就是一个很好的例子。Tan Li Hau,他在分流问题和修复bug方面提供了很大的帮助,还有Thiago Arrais,他在实施管道运营商方面提供了帮助
在其他新闻中,我们刚刚宣布开始我们自己的播客!如果你错过了,请查看我们的播客。如果你错过了,请查看我们昨天的文章。
我们的工作也是由我们的赞助商促成的。我们要感谢Discord和clay成为OpenCollective的银牌赞助商,也要感谢Linkedin成为GitHub上Henry的银牌赞助商!
特别感谢Handshake,一个与DNS兼容的去中心化、无权限的命名协议,在去年捐赠了10万美元作为他们FOSS社区资助的一部分,他们向Apache、Debian、EFF和Babel等各种开源社区认捐了1020万美元。
如果你或你的公司想支持Babel和JavaScript的发展,但不确定如何支持,你可以在Open Collective上赞助我们,更好的是,直接与我们合作实施新的ECMAScript提案作为一个志愿者驱动的项目,我们依靠社区的支持,既为我们支持广大的JavaScript用户提供资金,又能掌握代码的所有权。如果你想进一步讨论,请联系Henry,henry@babeljs.io!
F#管道操作员
⚠️管道操作符提案仍处于第一阶段,因此其规范仍在定义中。
这个提案有几个变体,正在思考中。通过测试这个插件,你可以帮助提案作者收集关于管道如何工作的反馈。但也要注意,如果语义在整个提案过程中发生了变化(他们会的),就需要重构了。
从7.3.0版本开始,Babel支持管道操作者提案的智能变体,从7.0.0-beta版本开始支持"最小 "变体。
在Thiago Arrais和James DiGioia的共同努力下,你现在也可以测试"#"变体了。如果你对这个具体的建议变体有想法或意见,你可以联系James。
F#变体与Smart变体有什么不同?我们没有使用 "主题引用 "的概念(# ),而是使用了箭头函数。这样做的好处是与当前的JavaScript更相似,但代价是语法稍显简练。
| 当前的JavaScript | F#管道 | 智能管道 |
|---|---|---|
let newScore = boundScore(
0,
100,
add(7, double(person.score))
);
|
let newScore = person.score
|> double
|> n => add(7, n)
|> n => boundScore(0, 100, n);
|
let newScore = person.score
|> double
|> add(7, #)
|> boundScore(0, 100, #);
|
虽然这两个提案并不相互依赖,也没有被作为一个单一的提案来开发,但你可以在使用F#管道的同时使用部分应用(从Babel 7.4.0开始支持)。
let newScore = person.score
|> double
|> add(7, ?)
|> boundScore(0, 100, ?);
请注意,虽然它看起来和 "智能 "管道的变体一样,但部分应用建议只支持函数调用参数中的? 。这意味着,例如,person |> #.score 是一个有效的 "智能 "管道,其F#等价物必须使用一个箭头函数:person |> p => p.score 。
关于如何处理await ,F#管道操作员也是不同的。
| 当前的JavaScript | F#管道 | 智能管道 |
|---|---|---|
let id = (
await (
await fetch(url)
).json()
).ID;
|
let newScore = fetch(url)
|> await
|> r => r.json()
|> await
|> obj => obj.ID;
|
let newScore = fetch(url)
|> await #
|> #.json()
|> await #
|> #.ID;
|
如果你想测试这个新的提案变体,你可以在你的Babel配置中添加@babel/plugin-proposal-pipeline-operator 。
module.exports = {
plugins: [
["@babel/proposal-pipeline-operator", { proposal: "fsharp" }]
]
};
你也可以通过启用 "Stage 1 "预设,在rep中进行尝试。
动态导入
虽然Babel已经支持解析动态导入import(source) ,但一直没有一个统一的转换方式:
- 如果您使用
webpack或rollup,您只需要包含@babel/plugin-syntax-dynamic-import,而不需要用Babel进行转换。 - 如果你使用Node,你可以使用
babel-plugin-dynamic-import-node插件来改造它 - 如果你使用SystemJS,
@babel/plugin-transform-modules-systemjs,结合@babel/plugin-syntax-dynamic-import,对其进行转换,而不明确启用转换插件。import()
由于动态导入建议最近被合并到主规范中,我们决定将这些用例统一到一个入口点:@babel/plugin-proposal-dynamic-import 。这个插件必须和一个模块转换插件一起使用,因为Babel需要知道你针对的是哪个模块加载系统。当以CommonJS为目标时,它内部委托给了 babel-plugin-dynamic-import-node.
例如,这是一个有效的配置:
module.exports = {
plugins: [
"@babel/plugin-proposal-dynamic-import",
"@babel/plugin-transform-modules-amd"
]
};
虽然这不是:
module.exports = {
plugins: [
"@babel/plugin-proposal-dynamic-import"
]
};
如果你想只允许解析import() 表达式而不对其进行转换,你可以只包含@babel/plugin-syntax-dynamic-import 包。
如果你使用@babel/preset-env ,动态导入支持将被默认启用。你不需要担心webpack 或rollup 的支持,因为babel-loader 和rollup-plugin-babel 都会自动禁用 Babel 变换,以使捆绑器能够正确处理它。
defaults @babel/preset-env 中的 browserslist 查询
当@babel/preset-env 没有传递任何目标时,它会在你的代码上运行每一个语法转换(模仿现在已经废弃的babel-preset-latest )。
为了支持这种行为,我们不得不解决Browserslist本身有默认选择的问题。这导致@babel/preset-env ,不允许使用default 查询。
@babel/preset-env 现在,当直接向预设传递目标时,支持 查询。defaults
module.exports = {
presets: [
["@babel/preset-env", {
targets: { browsers: "defaults" }
}]
]
};
你也可以使用.browserslistrc 文件来设置它,这也被其他工具如Autoprefixer或Stylelint 使用。
@babel/preset-env 的默认行为仍然是编译一切,但我们可能会在Babel 8中切换到使用这个defaults 查询。
实验性的TypeScriptnamespaces 支持
到目前为止,命名空间是Babel不支持的第二大TypeScript特性(第一个是类型检查!😛)。感谢社区成员Wesley Wolfe所做的工作,现在你可以在TypeScript插件中启用对它们的实验性支持,使用@babel/plugin-transform-typescript 的allowNamespaces 选项。
module.exports = {
plugins: [
["@babel/plugin-transform-typescript", {
allowNamespaces: true
}]
]
}
然后,你就可以在你的代码中使用命名空间了。
namespace Validation {
const lettersRegexp = /^[A-Za-z]+$/;
const numberRegexp = /^[0-9]+$/;
export class LettersOnlyValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
}
⚠️警告 ⚠️
当TypeScript支持最初被添加到Babel时,
namespaces,因为它们需要的类型信息只有完整的TypeScript编译器和类型检查器才能提供。由于这个原因,目前这个(实验性)支持有一些限制:
- 命名空间只能导出不可变的绑定关系
- 当合并具有相同名称的多个命名空间时,它们的范围不会被共享
你可以在
@babel/plugin-transform-typescript文档中找到完整的注意事项清单。