【问题标题】:Use Native ES6 and Transpiling When Needed在需要时使用原生 ES6 和转译
【发布时间】:2015-08-15 15:48:27
【问题描述】:

有没有办法(使用 grunt、gulp、plain JS、node 模块等)来做以下事情。

以 JS 文件为输入,根据浏览器当前对 ES6 特性的支持构建一系列浏览器特定文件,并转译尚不支持的特性。

我想使用可用的 ES6 特性,并将不可用的特性转换为 ES5。

此外,对于我们这些乐于处理旧浏览器(例如 IE9、IE10 和即将成为 IE11)的人来说,除了转换我永远编写的所有 JS 之外,还需要某种处理它们的过程最终出来:)。

【问题讨论】:

  • 我没听说过,但也想过这个。
  • 一个有趣的想法(我也考虑过一次),如果它被广泛使用,它可能会推动 ES6 在浏览器中的实现。但是,请参阅Why not sending JavaScript files in browser-specific bytecode? 了解一些相反的论点(当然,并非所有论点都适用)
  • 对于 IE 等运行缓慢的浏览器,您也许可以这样做,但发布周期紧且支持部分功能的常青浏览器会困难得多
  • 更困难但并非不可能:)。 Chrome 和 FF 是真正的快速推动者,根据他们对特定版本的要求,发布通常至少相隔一个月。我可以查一下,但我太懒了。

标签: javascript ecmascript-6 fallback


【解决方案1】:

您显然是指为不同的浏览器分别构建,您可能会根据某种用户代理嗅探来提供这些构建,或者在浏览器端功能检测后动态加载。这听起来很复杂且容易出错。随着新浏览器版本的出现,您还需要不断地重建特定于浏览器的版本,例如支持胖箭头的 Chrome 版本。

您要解决的问题是什么?你相信原生实现会更快吗?这是可能的,但不一定是这样,如果存在差异,则可能很小。您是否担心有效负载大小,因为 ES6 语法通常更简洁?一旦 JS 被缩小和压缩,这种差异也可能可以忽略不计。我宁愿在所有浏览器中运行相同的 ES5 转译代码,并避免跟踪某些浏览器对某个 ES6 功能的支持的奇怪错误,你认为这可以让你避免转译,结果却是不稳定的.

我会给你一个具体的例子。假设您决定为 node 编译的代码不需要转换粗箭头,因为您听说 node 使用 --harmony 标志支持它们。所以你写

var foo = {
  x: 42,
  bar: function() { setTimeout(() => console.log(this.x)); }
};  
foo.bar();

但后来你发现节点不支持胖箭头函数中this的词法化:

> node --harmony test.js
< undefined

难道你不想让一个像 babel 这样的编译器可靠地将它转换成正确的 ES5 吗?

var foo = {
  x: 42,
  g: function g() {
    var _this = this;
    setTimeout(function () {
      return console.log(_this.x);
    });
  }
};

> babel-node test.js
< 42

一旦你对你想要支持的所有浏览器都实现了特定的 ES6 特性感到满意,那么大多数转译器都会提供逐个特性的标志,允许你告诉它跳过它。

您的提议的修改版本是有两个版本,一个完全转译,一个未转译,用于完全支持 ES6 的浏览器。这将允许您避免在后一种情况下必须包含转译器的运行时(例如 babel 的 browser-polyfill.js)。但是,它也会阻止您利用 babel 对 ES7 功能的支持,其中一些非常有用,例如异步函数。

【讨论】:

  • 我假设人们会在特征检测后动态加载构建的脚本,而不是基于 UA 嗅探来提供它们(这也有其他几个原因也很糟糕)
  • @Bergi:但这会显着影响渲染(/使用)的时间。
  • @FelixKling:您可能会想出一个自适应解决方案,首先尝试(对于未知用户代理)纯 ES6,然后优雅地降级为需求较少的转译脚本。
  • @Bergi:是的。我正在考虑根据 kangax 兼容性表中的数据为每个最新浏览器提供一个转换版本。理想情况下,浏览器测试将由网络服务器本身负责。如果只有 UA 字符串更可靠:-/ 但也许如果将这样的功能添加到 Web 服务器,UA 会被欺骗更少。一个人可以梦想:)
  • @torazburo:大部分是准确的,精明的观点,但你说过的一件事是:“一旦你对你想要支持的所有浏览器都实现了特定的 ES6 特性感到满意”对我和大多数人来说都是一个问题在我们处理那些不可更新的浏览器(例如 IE)并且只要它们存在就永远不会支持 ES6 时,很可能会在很长一段时间内发生。因此,尽管它可能很糟糕,但我们必须想出一些东西来支持那些从不支持 ES6 的浏览器,而我的浏览器也要支持这些浏览器,因为它们正朝着完全兼容 ES6 的方向发展。
猜你喜欢
  • 2016-06-07
  • 2017-04-12
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 2019-10-20
相关资源
最近更新 更多