使用ES6和ES7功能的Javascript库是否需要babel-polyfill?

时间:2016-01-23 11:32:02

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

我正在开发一个大量使用ES6和ES7功能的库。用Babel编译它会产生代码,它(自然地)使用符号或Promise等原语。我应该babel-polyfill确保这些基元确实存在吗?

在第一时间,答案似乎是'是' - 特别是如果我不知道有人可以执行我的lib的运行时间。另一方面,如果每个库都这样做,我们最终会反复要求{{1}}(我不确定这是不是一个好主意)。

1 个答案:

答案 0 :(得分:6)

我对此做了一些研究:

从lib内部要求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)。我的建议是 - 不要为此目的使用插件。

相关问题