资讯专栏INFORMATION COLUMN

babel-polyfill的相关知识

seal_de / 1204人阅读

摘要:与简单来说包括了和转义和的包。虽然实际压缩已经能够优化掉大部分体积的,但是对于一些最新浏览器版本来说,任何的都是浪费资源的。以服务端渲染的方式从请求中获取到的信息,然后返回对应的。

使用@babel/polyfill可以让你在任何es2015+的环境中编写代码,而不需要担心兼容性问题。它会在全局变量上添加一些类似于原生的方法。但是webpack一直以来配置都特别复杂,直到webpack4才开始做0配置。项目中如果需要webpack的配置可能都是ctrl+c ctrl+v,没有及时去更新,会对polyfill有一些误解,比如说,项目中会同时出现babel-plugin-transform-runtimebabel-polyfill,在已经使用了babel-polyfill的基础上还是会担心使用新语法带来的问题。这篇文章将会解答一些与babel-polyfill相关的问题。

polyfill与core-js

简单来说polyfill包括了core-jsregenerator-runtime(转义async和await的包)。

而且babel7.4.0开始@babel/polyfill改成直接引入core-jsregenerator-runtime

As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions):
import "core-js/stable";
import "regenerator-runtime/runtime";

polyfill与preset-env

preset-env中我们需要关注以下两个属性

targets

targets可以设置polyfill引入哪些方法的转义,因为preset-env有一个内置的json文件,可以根据用户设置过滤所需要polyfill的方法

// corejs2-built-ins.json
    {
    "es6.array.copy-within": {
        "chrome": "45",
        "edge": "12",
        "firefox": "32",
        "safari": "9",
        "node": "4",
        "ios": "9",
        "samsung": "5",
        "opera": "32",
        "electron": "0.35"
      },
      "es6.array.every": {
        "chrome": "5",
        "opera": "10.10",
        "edge": "12",
        "firefox": "2",
        "safari": "3.1",
        "node": "0.10",
        "ie": "9",
        "android": "4",
        "ios": "6",
        "phantom": "2",
        "samsung": "2.1",
        "electron": "1.1"
      },
    ……
    }

// 根据项目需要兼容的最低版本
{
  "targets": {
    "chrome": "58",
    "ie": "11"
  }
}
useBuiltIns

useBuiltIns有两个特别有用的属性,usage和entry,使用两个属性都是直接引用core-js对应的包。

entry的用法:项目中import "@babel/polyfill";persets的options中使用useBuiltIns: "entry",配合targets选项,只import最低版本所需要的方法垫片

usage的用法:只需要在persets的options中使用useBuiltIns: "usage"即可将所有项目中用到所需要在最低浏览器版本不兼容的方法垫片,例如 includes 方法就会自动import "core-js/modules/es6.string.includes";`

//demo
// index.js
console.log("test123".includes("test"));
// webpack.config.js
use: {
    loader: "babel-loader",
    options: {
        presets: [
            [
                "@babel/preset-env",
                {
                    targets: {
                        chrome: "58",
                        ie: "11"
                    },
                    useBuiltIns: "usage"
                }
            ]
        ]
    }
}

因为 includes 在 ie11 中不兼容,打包结果:

不使用@babel/preset-env,打包后文件 _900 多 bytes 不到 1kb_,不能兼容低版本浏览器

使用preset-env+useBuiltIns: "usage",babel 识别到使用了 includes 方法,加入 polyfill 的方法有[ "es6.string.includes", "es7.array.includes" ],打包后文件为 6.56kb

使用preset-env+useBuiltIns: "entry",并且手动 import @babel/polyfill(使用 useBuiltIns webpack 都会建议不需要手动 import polyfill,如果它检测到用户已经 import 了会提示 useBuiltIns 选用 entry 属性),polyfill 的几十个方法,也就是按照 targets 的配置将所有需要 polyfill 方法都打包进来,打包后文件为 76.7kb

{
  "es6.array.copy-within",
  "es6.array.fill",
  "es6.array.find",
  "es6.array.find-index",
  "es7.array.flat-map",
  "es6.array.from",
  "es7.array.includes",
  ……
}

只使用 babel-loader+@babel/preset-env,打包文件大小为 86.3kb

因此,如果项目本身是有兼容性要求的话,一般都会使用 babel-loader 做兼容,因为很常见的 array.from 也是要做 polyfill 的,加上 preset-env + useBuiltIns 按需加载使用一些新语法其实不需要太担心包大小的问题,也不需要手动 import @babel/polyfill

虽然在babel-preset-env官方文档中看到usage还是experiment状态,但是可以在vue-cli的源码看到默认打包的app的presets配置里useBuiltIns是usage,所以可以放心的用(其实babel6的时候usage就已经是experiment,babel7也还是)

/vue-cli/packages/@vue/babel-preset-app/index.js

需要注意的是如果你使用的不是TC39 stage4的提案,你还是需要自己手动去设置babel-plugin,preset-env不会帮你引入其他stage的语法垫片

polyfill 与 plugin-transform-runtime

如果有长时间使用过webpack,一定不会对babel-plugin-transform-runtime这个插件陌生,大家都有做兼容的环境的作用,甚至有些项目还会看到同时使用babel-polyfillbabel-plugin-transform-runtime,这种做法貌似在babel-preset-env出来之前是有一定道理的。

实际上transform-runtime的转换是非侵入性的,也就是它不会污染你的原有的方法,比如挂在Array原型上的includes方法就只能使用babel-polyfill

transform-runtime的使用场景应该是库,遇到需要转换的方法它会另起一个名字,否则会直接影响使用库的业务代码,平常的项目使用babel-polyfill即可。

polyfill.io

虽然presets-env+实际压缩已经能够优化掉大部分体积的polyfill,但是对于一些最新浏览器版本来说,任何的polyfill都是浪费资源的。

这时候polyfill.io能够解决这个问题。polyfill.io以服务端渲染的方式从请求中获取到useragent的信息,然后返回对应的polyfill。但据说是因为浏览器版本太多,国内还有套壳的360/qq等浏览器,ua要是判断失误没有其他回退的方案,因此没有办法广泛应用起来。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104999.html

相关文章

  • Babel使用

    摘要:使用的时候只需要安装你想要的阶段就可以了然后添加进你的配置文件。为了显出的能耐,我们分别配个用和支持的先来配使用的首先安装然后配置需要注意的是,虽然没有出现在配置里,但仍然需要安装,因为依赖它。 Babel介绍 Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本。 这一过程叫做源码到源码编译, 也被称为转换编译。 15 年 11 月,Babel...

    Y3G 评论0 收藏0
  • webpack4 系列教程(二): 编译 ES6

    摘要:今天介绍怎么编译的各种函数和语法。对于相关的匹配规则,除了匹配结尾的文件,还应该去除文件夹下的第三库的文件发布前已经被处理好了。它需要在我们项目的入口文件中被引入,或者在中配置。个人网站原文链接系列教程二编译 今天介绍webpack怎么编译ES6的各种函数和语法。敲黑板:这是webpack4版本哦, 有一些不同于webpack3的地方。 >>> 本节课源码 >>> 所有课程源码 1....

    graf 评论0 收藏0
  • babel相关总结

    对babel一直没具体总结过,趁周末看了下文档,记录一下 babel作为一个compiler,主要用在转换新的es标准实现来使所有浏览器都支持,这包含两方面 新的es标准语法,箭头函数、扩展运算符、块级作用域等 转化新的es标准方法或正被提议还未纳入标准的方法,,Array.from、Map、Promise、String.includes等 babel编译过程 babel的编译过程分为三个阶段...

    Richard_Gao 评论0 收藏0
  • babel学习笔记

    摘要:经过一番折腾,总算是把自己项目里的配置调整好了,所有文件从原来的缩小到。折腾了不少时间,改动其实就一个地方,就是配置文件,记录一下自己折腾的过程。本以为那这两种方式取其一就行了。这感觉和想象中的不一样啊,说好的一个搞定一切的呢。。。 先是看到前端早读课【第1065期】再见,babel-preset-2015,听说现在有了babel-preset-env,别的什么preset都不需要了,...

    Aomine 评论0 收藏0
  • Babel 配置工程师应知应会

    摘要:,标题党了,本文仅介绍相关生态和一些配置心得。函数是在时候常用的工具函数,对编译模块时,会将用到的放到模块顶部。用来看最终引入了哪些必须配合,貌似加入了此项以后,会得到类似于的效果。 Babel Sorry,标题党了,本文仅介绍 Babel 相关生态和一些配置心得。 Babel 各个 package 的用途 babel-core: 核心部分 babel-cli: 允许使用命令行 ...

    caikeal 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<