5

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

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

4

1 回答 1

6

我对此做了一些研究:

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

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

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

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

现在,你(可能)应该怎么做:

如果你在你的库中需要一个特定的特性(即 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)。我的建议是 - 不要为此目的使用插件。

于 2016-01-24T13:08:43.293 回答