babel-polyfill基本配置

2020-03-28 19:55:46Tags: javascript webpack

众所周知,Babel 是一个 JavaScript 编译器,Babel 通过语法转换器支持最新版本的 JavaScript,由于 Babel 只转换语法(如箭头函数), 你可以使用 babel-polyfill 支持新的全局变量,例如 Promise 、新的原生方法如 String.padStart (left-pad) 等。

使用babel-polyfill的方法一般为分四种

阅读本文需要有webpack和babel配置基础

方法一:

直接走cdn,并加载在html的head里,这样做的优点是,不需要打包进自己的业务代码里,利用cdn的加速和缓存能起到很好的优化效果,缺点就是会多一个请求,而且是全量的引入所有的polyfill,假如我只需要支持chrome 55+的浏览器环境,那么这种方法就不太好了,这里推荐几个国内外的免费cdn服务

BootCDN

<script src="https://cdn.bootcss.com/babel-polyfill/6.26.0/polyfill.min.js"></script>

cdnjs

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>

75CDN

<script src="http://lib.baomitu.com/babel-polyfill/6.26.0/polyfill.min.js"></script>

方法二:

通过在babel配置文件中指定浏览器版本,就能够实现自动打包,从而减少打包的体积,这里是基于Env preset

npm install babel-preset-env --save-dev
// 或
yarn add -D babel-preset-env

配置.babelrc

{
  "presets": ["env"]
}

这里没有任何选项,将全量转换

添加一些选项,如浏览器版本或环境

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      },
      "useBuiltIns": true
    }]
  ]
}
{
  "presets": [
    ["env", {
      "targets": {
        "node": "6.10"
      }
    }]
  ]
}

其他选项

targets.node 支持到哪个版本的 node
targets.browsers 支持到哪个版本的浏览器
targets.uglify 压缩代码
spec 对在这个 preset 中支持它们的插件启用更符合规范,但可能较慢的方式
loose 启动宽松模式,配合 webpack 的 loader 使用
modules 模块类型
debug 开启调试模式
include 包含一些插件
exclude 排除一些插件 useBuiltIns 是否对 babel-polyfill 进行分解,只引入所需的部分

选项详细请查看官方文档

npm install babel-polyfill --save
// 或
yarn add babel-polyfill

在业务代码中的引用方式,只需要在入口文件最顶部引入一次即可

import "babel-polyfill";

这里有个注意事项,如果你想排除一些插件,如你已经通过cdn直接引入了es6-promise,并不想babel-polyfill在打包的时候再引入一个promise插件,"exclude": ["es6.promise"],那么在引入babel-polyfill的时候只能在入口文件中引入,不能放在webpack的entry里(经个人测试,在entry里会全部打包,并不会根据配置文件排除对应的插件)

方法三:

手动引入所需要的方法垫片 首先

npm install core-js --save
// 或
yarn add core-js
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";
import "core-js/modules/web.timers";
import "core-js/modules/web.immediate";
import "core-js/modules/web.dom.iterable";

这样做的优点在于,能最小化代码体积,需要什么用什么,没有冗余的代码,缺点就是不够智能,繁琐。

方法四:

第四种方法其实就是第二种中提到的,直接在webpack的entry中引用,全量打包

{
    entry: ['babel-polyfill']
}

注意

polyfill的原理是污染原生对象,如Array.prototype.includes是es2016+规范中的新增的,而在ie11中Array的原型上并没有此方法,那么polyfill就会在原生对象中增加这个方法,这样的做法虽然能够很好地填充浏览器对语法支持不足,但同时也带来风险,污染了全局对象,如果你能保证整个项目中代码风险可控,那么就可以使用此工具来修补低版本浏览器的语法支持不足。

讲完了三种方法,那么这三种方法应该在什么场景下用呢?

  • 方法一,不在乎polyfill的代码体积及多一个请求那么就选择此方法。
  • 方法二,项目只需要兼容某些特定环境,如chrome55+,并且想在打包的时候减小代码体积,那么就可以使用此方法的配置。
  • 方法三,项目中需要哪些方法就只引入哪些,做到体积最小
  • 方法四,不在乎体积不在乎版本直接全量打包。