我正在开发一个大量使用ES6和ES7功能的库。用Babel编译它会产生代码,它(自然地)使用符号或Promise等原语。我应该babel-polyfill
确保这些基元确实存在吗?
在第一时间,答案似乎是'是' - 特别是如果我不知道有人可以执行我的lib的运行时间。另一方面,如果每个库都这样做,我们最终会反复要求{{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)。我的建议是 - 不要为此目的使用插件。