Skip to content

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

Open
@lmk123

Description

@lmk123
Owner

先简述一下 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。

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

Activity

yoyeung

yoyeung commented on Jul 15, 2016

@yoyeung

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

lmk123

lmk123 commented on Jul 15, 2016

@lmk123
OwnerAuthor

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

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

yoyeung

yoyeung commented on Jul 16, 2016

@yoyeung

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

conanliu

conanliu commented on Dec 17, 2016

@conanliu

@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

kangaoxiaoshi commented on Mar 22, 2017

@kangaoxiaoshi

@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

scopewu commented on May 12, 2017

@scopewu
JoeeeeeWu

JoeeeeeWu commented on Jul 27, 2017

@JoeeeeeWu

你最上面说的这一句话:

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

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

@lmk123

xuqinggang

xuqinggang commented on Dec 11, 2017

@xuqinggang

transform-runtime默认配置polyfill为true。

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

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

9 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @tvrcgo@yoyeung@zhishaofei3@webjohnjiang@lmk123

        Issue actions

          transform-runtime 会自动应用 polyfill,即便没有使用 babel-polyfill · Issue #45 · lmk123/blog