Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transform-runtime 会自动应用 polyfill,即便没有使用 babel-polyfill #45

Open
lmk123 opened this issue Jul 5, 2016 · 13 comments
Labels

Comments

@lmk123
Copy link
Owner

lmk123 commented Jul 5, 2016

先简述一下 babel-polyfilltransform-runtime 是做什么的。

目前浏览器对 ES2015 语法的支持都不太好,所以当我们需要使用 PromiseSetMap 等功能时就需要 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。

这可能并不是我们想要的。

@yoyeung
Copy link

yoyeung commented Jul 15, 2016

奇怪的是已使用transform-runtime 但是Array.find 是undefined

@lmk123
Copy link
Owner Author

lmk123 commented Jul 15, 2016

@yoyeung 我刚才试了一下,不用 babel-polyfill 只用 transform-runtime 的话,Array.prototype.find 确实是 undefined

也许在没有 babel-polyfill 的情况下,transform-runtime 只会把 built-ins(比如 PromiseSymbol)给加进去吧,等我有空了就验证一下。

@yoyeung
Copy link

yoyeung commented Jul 16, 2016

謝謝。。。。這個問題有點困擾
我的解決方法是人工加入

@conanliu
Copy link

@yoyeung 刚好路过,也遇到过这个问题,这其实是配置不对,官方推荐的用法是:

// with options
{
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}

这样是不会自动polyfill各种ES6/7方法的,只要把polyfill改成true即可,babel会自动识别代码里用到了哪些对象方法(只要不是特别奇葩的用法比如Object['assign']),并自动polyfill这些方法。而这其实是默认开启的,所以可以简写成:

// with options
{
  "plugins": [
    "transform-runtime"
  ]
}

@kangaoxiaoshi
Copy link

@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
Copy link

scopewu commented May 12, 2017

@kangaoxiaoshi
You can see transform-runtime

@JoeeeeeWu
Copy link

你最上面说的这一句话:

在转换 ES2015 语法为 ECMAScript 5 的语法时,babel 会需要一些辅助函数,例如 _extend。babel 默认会将这些辅助函数内联到每一个 js 文件里,这样文件多的时候,项目就会很大。

其中的辅助函数指的是babel因为设置了babel-preset-2015转换语法而生成的,还是通过单独的一个es6的API转换插件比如babel-plugin-transform-object-assign转换生成的,还是怎么生成的?

@lmk123

@xuqinggang
Copy link

transform-runtime默认配置polyfill为true。

"plugins": [
["transform-runtime"]
]

亲测,会转换如文档所说的构建Promise,Set,Map等实例的语法文档地址
我也试了下如Array.find等API方法,不加babel-polyfill,transform-runtime默认配置也会转换es6的API为 es5

@terminalqo
Copy link

在转换 ES2015 语法为 ECMAScript 5 的语法时??

@Jmingzi
Copy link

Jmingzi commented Jun 8, 2018

总结:

  • 第一个目的避免重复引用工具类好理解
  • 第二个目的是提供运行时的helper,polyfill与regenerator支持。babel-polyfill是全局污染的,babel-runtime则是直接重写的方法来让你使用。

那么接下来的问题是,babel-runtime到底polyfill了哪些?
引用这篇文章

它不模拟实例方法,即内置对象原型上的方法,所以类似Array.prototype.find,你通过babel-runtime是无法使用的。

但我无从考证。官方文档上如是说:

这意味着你可以无缝的使用这些原生内置的和静态方法,且无需担心它们的来源。
注意: 例如 "foobar".includes("foo") 等实例方法将不会正常工作。

@tvrcgo
Copy link

tvrcgo commented Jun 22, 2018

@kangaoxiaoshi 只启用 transform-runtime ,Array.prototype.findIndex 已经注入了,是你版本问题?

env:

@webjohnjiang
Copy link

大家要区分Array.from还是Array.prototype.findIndex。 前者是类的方法,后者是内置对象原型上的方法。 transform-runtime和babel-runtime无法polyfill对象原型上的方法~ 但能polyfill Array.from.

关于transform-runtime解决的问题,我这里有一篇比较啰嗦的实验性文章 从零搭建webpack前端类库脚手架[3]-强悍的babel

@zhishaofei3
Copy link

Array.prototype.findIndex

请问你是怎么用的?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests