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

Tom*_*ich 4 javascript polyfills ecmascript-6 babeljs ecmascript-7

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

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

Tom*_*ich 6

我做了一些研究:

需要babel-polyfill从LIB貌似反模式内; 这有两个原因:

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({})
Run Code Online (Sandbox Code Playgroud)

转化为类似于:

var _keys=require("babel-runtime/core-js/object/keys")
_keys(obj)
Run Code Online (Sandbox Code Playgroud)

var aaa = Object
aaa.keys(obj)
Run Code Online (Sandbox Code Playgroud)

根本没有变换,因此将失败(如果没有浏览器或polyfill定义Object.keys).我的建议是 - 不要为此目的使用插件.