7.5.0发布:动态导入和F#管线

126 阅读6分钟

7.5.0发布:动态导入和F#管道

今天我们发布了Babel 7.5.0!

这个版本包括对几个ECMAScript提案的改进支持:Stage 1管道操作员的F#变体和Stage 4动态import() 提案的官方插件(同时支持preset-env )。它还支持TypeScriptnamespaces(实验性)和Browserslist的default 查询,在preset-env

你可以在GitHub上阅读整个更新日志。

感谢Wesley WolfeMartin ZlámalBlaine BublitzLetladi SebeshoPaul ComaniciLidor AvitanArtem ButusovSebastian JohanssonMin ho Kim的第一次PR

我们一直在寻找帮助,特别是在分流问题、审查拉动请求和在Slack上帮助人们。我们正在尝试使用GitHub实施的新的分流角色,我们希望表彰社区中那些愿意站出来帮助我们的人!😉

巴别组织的最新成员就是一个很好的例子。Tan Li Hau,他在分流问题和修复bug方面提供了很大的帮助,还有Thiago Arrais,他在实施管道运营商方面提供了帮助

在其他新闻中,我们刚刚宣布开始我们自己的播客!如果你错过了,请查看我们的播客。如果你错过了,请查看我们昨天的文章

我们的工作也是由我们的赞助商促成的。我们要感谢Discordclay成为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 ArraisJames DiGioia的共同努力下,你现在也可以测试"#"变体了。如果你对这个具体的建议变体有想法或意见,你可以联系James

F#变体与Smart变体有什么不同?我们没有使用 "主题引用 "的概念(# ),而是使用了箭头函数。这样做的好处是与当前的JavaScript更相似,但代价是语法稍显简练。

当前的JavaScriptF#管道智能管道
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#管道操作员也是不同的。

当前的JavaScriptF#管道智能管道
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) ,但一直没有一个统一的转换方式:

  • 如果您使用webpackrollup ,您只需要包含@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 ,动态导入支持将被默认启用。你不需要担心webpackrollup 的支持,因为babel-loaderrollup-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 文件来设置它,这也被其他工具如AutoprefixerStylelint 使用。

@babel/preset-env 的默认行为仍然是编译一切,但我们可能会在Babel 8中切换到使用这个defaults 查询。

实验性的TypeScriptnamespaces 支持

到目前为止,命名空间是Babel不支持的第二大TypeScript特性(第一个是类型检查!😛)。感谢社区成员Wesley Wolfe所做的工作,现在你可以在TypeScript插件中启用对它们的实验性支持,使用@babel/plugin-transform-typescriptallowNamespaces 选项。

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 文档中找到完整的注意事项清单。