Babel 踩坑总结(二) —— babel-polyfill、babel-runtime 的选择

此篇来解决上篇提出的问题,官方给出babel-polyfillbabel-runtime 两种解决方案来解决这种全局对象或全局对象方法不足的问题

1. babel-polyfill

官方手册

babel-polyfill 会在应用中模拟一个 es2015+ 的环境,对新语法需要的新对象进行补全

使用 babel-polyfill 后,可以使用内置对象如 PromiseWeakMap,静态方法如 Array.fromObject.assign,实例方法如 Array.prototypes.includes 以及 generator 函数

下载 babel-polyfill

npm i babel-polyfill --save

因为这是一个 polyfill(需要在你的源代码之前运行),所以需要它是一个 dependency,而不是 devDependency

1.1 几种引入方式

引入方式很简单,在入口文件引入 babel-polyfill 就好了

require('babel-polyfill')或者es6的 import 'babel-polyfill'

如果是使用 webpack 可在 webpack.config.js 进行如下配置

module.exports = {
  entry: ["babel-polyfill", "./app/js"],
};

1.2 babel-polyfill 的一些缺陷

  1. babel-polyfill 可能会增加很多根本没有用到的 polyfill;
  2. 可能会污染子模块的局部作用域,严重的可能会导致冲突

使用 babel-polyfill 前的包大小

在这里插入图片描述

使用 babel-polyfill 后的包大小

在这里插入图片描述

2. babel-runtime

接着是 babel-runtime,简单说 babel-runtime 更像是一种按需加载的实现,比如你哪里需要使用 Promise,只要在这个文件头部 import Promise from 'babel-runtime/core-js/promise' 就行了

下载 babel-runtime

npm install --save babel-runtime

不过如果你许多文件都要使用 Promise,难道每个文件都要 import 一遍不成?

当然不是,Babel 官方已考虑这种情况,只需要使用 babel-plugin-transform-runtime 就可以解决手动 import 的苦恼了

2.1 babel-plugin-transform-runtime

官方手册

在下载 babel-runtime 的基础上,下载 babel-plugin-transform-runtime

npm install --save-dev babel-plugin-transform-runtime

然后在 .babelrc 进行配置

{
  "plugins": ["transform-runtime"]
}
2.1.1 技术细节

总的来说,babel-plugin-transform-runtime 就是可以在我们使用新 API 时自动 import babel-runtime 里面的 polyfill,具体插件做了以下三件事情:

  • 当我们使用 async/await 时,自动引入 babel-runtime/regenerator
  • 当我们使用 ES6 的静态事件或内置对象时,自动引入 babel-runtime/core-js
  • 移除内联babel helpers并替换使用babel-runtime/helpers 来替换

使用 babel-plugin-transform-runtime 前包的大小

在这里插入图片描述

使用 babel-plugin-transform-runtime 后包的大小

在这里插入图片描述

2.2 babel-runtime 的优劣势

此处说的优缺点是默认使用了 babel-plugin-transform-runtime

优势

  • 不会污染全局变量
  • 多次使用只会打包一次
  • 依赖统一按需引入,无重复引入,无多余引入
  • 避免 babel 编译的工具函数在每个模块里重复出现,减小库和工具包的体积

劣势

  • 不支持实例化的方法如 Array.includes(x) 就不能转化
  • 如果使用的API用的次数不是很多,那么transform-runtime 引入polyfill的包会比不是transform-runtime 时大

3. 总结

babel-polyfill 是在原有的JS内置对象及方法上做向后兼容的处理,比如说ES5里面的 Object 是没有自带 assign 方法的,那么你加载了babel-polyfill 之后,它就给 Object 扩展了一个 assign 方法,这样你就可以直接使用 Object.assign(obj1, obj2)

babel-runtime 的方式则需要babel作为工具,在转换的过程中,检测到你使用了 Object.assign,而且你的 .babelrc 配置中需要对其做ES5兼容处理,那么结合 babel-plugin-transform-runtime,在该JS文件中引入 Object.assign 的Polyfill,这样也能实现 Object.assign 的功能,但是你无法在 Object 上直接找到 assign 的方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章