概述
@babel/polyfill & @babel/runtime 只做 API 的转换,不做语法转换。语法转换需要 @babel/preset-env。
@babel/polyfill
@babel/polyfill 顾名思义是垫片的意思,polyfill 会在原有的JS内置对象及方法上做向后兼容的处理。
使用方法:
第一步:安装 @babel/polyfill (记住必须是--save,因为垫片方法最后需要被打包到代码中)
npm install --save @babel/polyfill
第二步:在入口文件中引入 @babel/polyfill
import '@babel/polyfill';
优势:
1、功能齐全
劣势:
1、代码体积大
2、污染全局,跟一些第三方包一起使用的时候可能会有冲突
@babel/runtime
@babel/runtime更像是一种按需加载的实现,比如你哪里需要使用 Promise,只要在这个文件头部 import Promise from '@babel/runtime/core-js/promise'。
那么问题来了,如果你许多文件都要使用 Promise,难道每个文件都要 import 一遍不成?Babel 官方已考虑这种情况,只需要使用 @babel/plugin-transform-runtime 就可以解决手动 import 的苦恼了。
问题又来了,如何使用@babel/plugin-transform-runtime呢?使用的方法也很简单,我们可以在babel的配置文件添加相应的配置:"plugins":["transform-runtime"]
总的来说,@babel/plugin-transform-runtime 就是可以在我们使用新 API 时自动 import @babel/runtime 里面的 polyfill,具体插件做了以下三件事情:
1、当我们使用 async/await 时,自动引入 @babel/runtime/regenerator
2、当我们使用 ES6 的静态事件或内置对象时,自动引入 @babel/runtime/core-js
3、移除内联babel helpers并替换使用@babel/runtime/helpers 来替换
优势
1、不会污染全局变量
2、依赖统一按需引入
3、避免 babel 编译的工具函数在每个模块里重复出现,减小库和工具包的体积
劣势
1、不支持实例化的方法扩展
@babel/preset-env
babel-preset-env 是一些 babel 插件的集成,可以实现语法转换。在完成语法转换的同时,我们还可以通过配置引入需要的垫片方法,做到按需引入:
presets: [
[
'@babel/env', // @babel/preset-env 的缩写
{
targets: { // 目标浏览器
edge:'17',
firefox:'60',
chrome:'67',
safari:'11.1',
ie:'9'
},
useBuiltIns: 'usage', // 按需引入,不许手动引入额外东西,打包出的数据按需引入模块
corejs: {
version:3
}
}
]
]
注意:加了上面的配置以后,别忘了安装 corejs 模块,corejs 模块得通过 --save的模式安装!
如果@babel/plugin-transform-runtime也配置了corejs, 则preset-env的useBuiltIns就不会生效,以@babel/plugin-transform-runtime的配置为主,具体配置如下:
plugins: [
[
'@babel/plugin-transform-runtime',
corejs: {
version:3
}
]
]
结语
至此我们已经讲明白了三者的异同,当然 babel 还有很多的内容值得我们去研究,大家继续加油吧!