【问题标题】:Should Javascript library which uses ES6 and ES7 features require babel-polyfill?使用 ES6 和 ES7 特性的 Javascript 库是否需要 babel-polyfill?
【发布时间】:2016-01-23 11:32:01
【问题描述】:

我正在开发一个大量使用 ES6 和 ES7 特性的库。使用 Babel 编译它会生成代码,该代码(自然)使用 Symbol 或 Promise 等原语。我应该require('babel-polyfill') 来确保这些原语确实存在吗?

起初,答案似乎是“是” - 特别是如果我不知道有人可能在什么运行时执行我的库。另一方面,如果每个图书馆都这样做,我们最终会一遍又一遍地要求babel-polyfill(我不确定这是否是个好主意)。

【问题讨论】:

  • 我想现在任何可行的方法都是一种选择:)
  • "我们最终会一遍又一遍地需要 babel-polyfill" - 我看不出有什么问题。它只会被加载和执行一次。这就是模块的工作原理。
  • @Bergi 这取决于npm 的安装方式。如果npm 多次安装它,它也会被执行多次,实际上会抛出错误,看看这个:github.com/babel/babel/blob/master/packages/babel-polyfill/src/…
  • 顺便说一句,如果您当前构建了一个新库,您应该假设 ES2015 以使用所有无法转译的新功能(TCO、模块、代理)。即将添加主要浏览器支持。

标签: javascript ecmascript-6 babeljs polyfills ecmascript-2016


【解决方案1】:

我对此做了一些研究:

从库内部要求babel-polyfill 看起来像反模式;这有两个原因:

1) babel-polyfill 不喜欢被要求多次,如果你尝试这样做,它会抛出(见下面的注释)

2) 这样做会导致库的大小显着增加,因为您必须多次捆绑 polyfill。

仅当 npm 无法对多个 babel-polyfill 依赖项进行重复数据删除时,1) 和 2) 才相关。如果您使用旧版本的 npm 或由于依赖关系限制可能无法进行重复数据删除,则可能会发生这种情况。由于最新的不容易控制,我认为 1) 和 2) 都很严重。

现在,您(可能)应该如何做到这一点:

如果您需要 lib 中的特定功能(即 Promise),您可以专门 require 它(即不是整个 polyfill,只是该功能)。这种方法可以缓解 1) 并部分缓解 2)。

可能最好的方法是简单地警告您的用户,您的 lib 需要一些 ES6 功能,因此他们应该需要 polyfill。

第一种方法的好例子是

https://www.npmjs.com/package/promisify-node

这需要它自己的 A+ 兼容 Promise 版本。第二种方法的好例子是

https://github.com/ubolonton/js-csp

它使用生成器,但不确保它们确实存在(通常,仅使用 Babel 编译代码是不够的,您需要一个 polyfill 才能使它们工作)。

-------- 编辑 --------

我发现,babel-plugin-transform-runtime 可以完全用于这个问题:它允许您使用 ES6 / ES7 功能,而不会因需要 polyfill 而污染全局命名空间。故事的可悲部分是,这个插件非常有问题,可能是因为它从根本上很难完成这项工作。例如:

Object.keys({})

被转换成类似于:

var _keys=require("babel-runtime/core-js/object/keys")
_keys(obj)

但是

var aaa = Object
aaa.keys(obj)

根本不会被转换,因此会失败(如果浏览器和 polyfill 都没有定义 Object.keys)。我的建议是 - 不要为此目的使用该插件。

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 2016-07-19
    • 2018-01-15
    • 2017-11-26
    • 1970-01-01
    • 2019-10-01
    • 2018-06-04
    • 2020-01-19
    • 2015-10-09
    相关资源
    最近更新 更多