按需引入polyfill

**  参考文档:你真的会用 Babel 吗?node

在开发过程当中,若是咱们写的代码是es6语法的,其中有不少语法如:async、Array.isArray、Object.assign等等是低版本浏览器所不支持的。为了保证咱们写的es6语法可以在各个新旧客户端上撒欢跑,咱们须要引入polyfill对这些新的语法进行全局注入。react

不引入的结果是:页面报错webpack


如何引入polyfill?

方法1、es6

全局引入polyfill:在webpack的入口文件中引入:import '@babel/polyfill' ;web

它会让咱们程序的执行环境,模拟成完美支持 es6+ 的环境,毕竟不管是浏览器环境仍是 node 环境对 es6+ 的支持都不同。它是以重载全局变量 (E.g: Promise),还有原型和类上的静态方法(E.g:Array.prototype.reduce/Array.form),从而达到对 es6+ 的支持。不一样于 babel-runtime 的是,babel-polyfill 是一次性引入你的项目中的,就像是 React 包同样,同项目代码一块儿编译到生产环境。segmentfault

缺点:全局引入 @babel/polyfill 的这种方式可能会导入代码中不须要的 polyfill,从而使打包体积更大数组

改进:使用useBuiltInsenv 会自动根据咱们的运行环境,去判断须要什么样的 polyfill,并且,打包后的代码体积也会大大减少,可是这一切要配置 useBuiltIns,并且须要你安装 babel-polyfill,并 import。它会启用一个插件,替换你的import 'babel-polyfill',不是整个引入了,而是根据你配置的环境和我的须要单独的引入 polyfill。浏览器

用法:bash

{babel

"presets": [
    [
      "@babel/env",
      {
        "modules": "commonjs",  //设置ES6 模块转译的模块格式 默认是 commonjs
        "useBuiltIns": "usage", 
      }
    ]
  ],
}复制代码

开启 "useBuiltIns": "usage"后,打包后文件的大小明显缩小了。从857 KiB =》610 KiB

须要注意的是useBuiltIns:falseuseBuiltIns:entry的打包效果是同样的。而且使用了`useBuiltIns: 'usage'以后,就没必要手动在入口文件中`import '@babel/polyfill'` ,不然会有以下warning:

When setting `useBuiltIns: 'usage'`, polyfills are automatically imported when needed. Please remove the `import '@babel/polyfill'` call or use `useBuiltIns: 'entry'` + `import '@babel/polyfill'`instead.

方法2、在babelrc文件中配置@babel/transform-runtime 

{

"presets": [
    [
      "@babel/env",
      {
        "modules": "commonjs",  //设置ES6 模块转译的模块格式 默认是 commonjs
      }
    ]
  ],
  "plugins": [
    "@babel/transform-react-jsx", //若是是须要支持 jsx 这个东西要单独装一下。
    "@babel/transform-runtime", 
  ]
}复制代码

优势:transform-runtime会根据检测API是否须要重写,而后按需写入须要的API。这样就能够很大程度上减小打包文件的体积,并且 transform-runtime 不会污染原生的对象,方法,也不会对其余 polyfill 产生影响。因此 transform-runtime 的方式更适合开发工具包,库,一方面是体积够小,另外一方面是用户(开发者)不会由于引用了咱们的工具,包而污染了全局的原生方法,产生反作用,仍是应该留给用户本身去选择。

缺点:instance 上新添加的一些方法,babel-plugin-transform-runtime 是没有作处理的,好比 数组的 includes, filter, fill 等。举个例子,在代码中写了一个filter方法,在本身的浏览器运行完美。但测试小姐姐一测,发现她在浏览器上就没法使用某个功能,调试发现是 filter 不支持,难受不😣

总结

  • 打包体积:全局引入 @babel/polyfill + "useBuiltIns": "usage"的方式,能够根据环境判断要引入哪些prolyfill,这个能够有效减小打包后代码的体积;babel-polyfill 是配置了执行环境的,经过环境看你须要哪些 polyfill,而 transform-runtime,是发现咱们代码须要什么 polyfill就重写哪些polyfill。因此使用transform-runtime后打包体积是小于@babel/polyfill + "useBuiltIns": "usage"的。 
  • 全局污染:@babel/polyfill比较暴力,会重写代码中的原生对象、方法,而transform-runtime不会。 
  • polyfill的广度:instance 上新添加的一些方法,babel-plugin-transform-runtime 是没有作处理的,好比 数组的 includes, filter, fill 等
相关文章
相关标签/搜索