彻底弄懂babel配置
前言:babel 一个神奇的工具,可以让我们的代码随意跑在任何浏览器里面。但是很多人并不是特别理解babel的配置。这里我将写出我的心得。希望对大家有用。
一个简单的demo
src/index.js
let a = () => {}
new Promise(() => {});
[].includes(()=>{
console.log(1)
})
webpack.config.js 的配置
const path = require('path');
module.exports = {
mode: "development",
devtool: 'source-map',
context: process.cwd(),
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
"presets": [
[
"@babel/preset-env",
{}
]
],
"plugins": []
}
},
include: path.join(__dirname, 'src'),
exclude: /node_modules/
}]
}
}
知识点普及:babel 配置主要分成预设和插件, 预设可以理解没,是一个插件的集合。
根据上述配置,执行代码,得到如下结果:
我们发现, 只有语法被转换了,像全局方法Promise,与数组的原型方法。并有么做任何转换。这样子在低版本浏览器中,就会出现白屏的现象。因为全局方法与原因方法未做任何转换。
怎么办?
使用@babel/polyfill,修改配置如下:
module.exports = {
entry: ['@babel/polyfill', './src/index.js'],
module: {
rules: [{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
"presets": [
[
"@babel/preset-env",
{
useBuiltIns: "entry"
}
]
],
"plugins":
}
},
}]
}
}
不管三七二十一,将兼容包全部导入进来就可以兼容低版本了。
缺点:
- 体积增加到了470KiB, 压缩后 87.2 KiB,而原来只有 345 bytes,增加了好几百倍。
优化
还好babel7以后支持了按需引入。可以减少兼容包的体积,他只要的实现逻辑是: 遍历你的代码,找到需要引入的模块。从而减少打包体积。
配置:
"presets": [
[
"@babel/preset-env",
{
// debug:true, // 打开debug
useBuiltIns: "usage", // 按需引入
corejs: {
version: 3,
proposals: true
},
targets: { // 支持兼容的版本
android: '4.2',
ios: '9'
}
}
]
经过编译和打包后: 体积是114 KiB, 压缩体积是 19.8 KiB。体积小了许多。是不是已经很完美了!!!但是也有缺点。
缺点: 这种方式会在全局添加方法,和直接修改原型。 这样子会造成全局污染,如果别人也自定义扩展了同样的方法,则会出现相互覆盖的问题。
@babel/plugin-transform-runtime
此插件可以解决全局污染的问题。
更改配置
"plugins": [
[
'@babel/plugin-transform-runtime',{
corejs:3,
helpers: true,
regenerator: true
}
]
]
代码体积: 157 KiB,压缩后体积:26.7 KiB。 通过对比可知,体积稍微大了一点点。那么打包后的代码有什么区别了。我们一起来看一下。
没有配置transform-runtime 的编译代码
配置transform-runtime 之后的编译代码
我们发现 transform-runtime 把我们写的代码都改变了。进行了重新包装,这样子就不会有全局污染了。
总结:
体积 | 压缩后体积 | 结论 | |
---|---|---|---|
使用全量引入,@babel/polyfill | 470KiB | 87.2 KiB | 最好不要使用 |
按需引入 | 114 KiB | 19.8 KiB | 在项目开发中使用比较合适 |
transform-runtime | 157 KiB | 26.7 KiB | 在写库的时候比较合适 |
其实还有另一种方案,不过需要服务器配置成本比较大。
polyfill-service
- 自动化的 JavaScript Polyfill 服务
- Polyfill.io 通过分析请求头信息中的 UserAgent 实现自动加载浏览器所需的 polyfills
- polyfill-service
- polyfill-io
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
可以自己搭建服务器使用的。根绝浏览器,返回不同的兼容代码。