Description
先简述一下 babel-polyfill 与 transform-runtime 是做什么的。
目前浏览器对 ES2015 语法的支持都不太好,所以当我们需要使用 Promise
、Set
、Map
等功能时就需要 babel-polyfill 来提供。
在转换 ES2015 语法为 ECMAScript 5 的语法时,babel 会需要一些辅助函数,例如 _extend
。babel 默认会将这些辅助函数内联到每一个 js 文件里,这样文件多的时候,项目就会很大。
所以 babel 提供了 transform-runtime 来将这些辅助函数“搬”到一个单独的模块 babel-runtime 中,这样做能减小项目文件的大小。
今天我在写一个针对 Chrome 浏览器的项目的时候,使用了 transform-runtime,但没有用 babel-polyfill,因为很多 ES2015 的功能(比如 Promise
)Chrome 都已经支持了。可是文件经过 babel 转换之后,文件大小陡增,仔细一看,发现 babel 把 Promise
的 polyfill 给注入进来了。
因为我没有使用 babel-polyfill,所以我本来认为,babel 应该是不会给我注入任何 polyfill 的,但事与愿违。我查看了一下 babel-runtime,发现除了包含 babel 转换时需要用到的辅助函数外,它还包含了 corejs 与 regenerator——而 babel-polyfill 也包含了这两个模块。
当我查阅 transform-runtime 的文档时,才发现 transform-runtime 是可以配置的:
// with options
{
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
由此可见,当我们在配置里直接使用 "plugins": ["transform-runtime"]
时,其实就相当于引入了 babel-polyfill。
这可能并不是我们想要的。
Activity
yoyeung commentedon Jul 15, 2016
奇怪的是已使用transform-runtime 但是Array.find 是undefined
lmk123 commentedon Jul 15, 2016
@yoyeung 我刚才试了一下,不用 babel-polyfill 只用 transform-runtime 的话,
Array.prototype.find
确实是undefined
。也许在没有 babel-polyfill 的情况下,transform-runtime 只会把 built-ins(比如
Promise
和Symbol
)给加进去吧,等我有空了就验证一下。yoyeung commentedon Jul 16, 2016
謝謝。。。。這個問題有點困擾
我的解決方法是人工加入
conanliu commentedon Dec 17, 2016
@yoyeung 刚好路过,也遇到过这个问题,这其实是配置不对,官方推荐的用法是:
这样是不会自动polyfill各种ES6/7方法的,只要把
polyfill
改成true
即可,babel会自动识别代码里用到了哪些对象方法(只要不是特别奇葩的用法比如Object['assign']
),并自动polyfill这些方法。而这其实是默认开启的,所以可以简写成:kangaoxiaoshi commentedon Mar 22, 2017
@conanliu 不是这样吧! 当使用 transform-runtime 配置为
"plugins": [
["transform-runtime", {
"polyfill": true,
"regenerator": true
}]
]
Array.prototype.findIndex 是undefined
只有当使用babel-polyfill 时能找到Array.prototype.findeIndex
$export($export.P + $export.F * forced, 'Array', { findIndex: function findIndex(callbackfn/*, that = undefined */){ return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } });
从别的文章中我得到这么一段话:
transform-runtime 只能对语法进行解析如 await、async 等 但对Api不能够进行polyfill.
Ps: 到现在我都没能确切的理解transform-runtime到底能不能完全polyfill,以至于我们现在的解决方案是项目中使用到的新特性都会先用corejs先处理我们项目中用到了的语法和Api
scopewu commentedon May 12, 2017
@kangaoxiaoshi
You can see transform-runtime
JoeeeeeWu commentedon Jul 27, 2017
你最上面说的这一句话:
其中的辅助函数指的是babel因为设置了babel-preset-2015转换语法而生成的,还是通过单独的一个es6的API转换插件比如babel-plugin-transform-object-assign转换生成的,还是怎么生成的?
@lmk123
xuqinggang commentedon Dec 11, 2017
transform-runtime默认配置polyfill为true。
亲测,会转换如文档所说的构建Promise,Set,Map等实例的语法文档地址
我也试了下如Array.find等API方法,不加babel-polyfill,transform-runtime默认配置也会转换es6的API为 es5
9 remaining items