webpack关联babel手记
babel 是为了把高级JS语法转为低版本语法,它跟 webpack 是两个互不相关的工具,要想将它们关联起来,需要借助到:
1、 @babel/core:babel的核心模块
2、 babel-loader :把 babel 和 webpack 进行关联的桥梁
3、@babel/preset-env:预设
// 安装完之后去 rules 中进行配置
{
test: /\.js$/, // babel是处理js的
use: {
loader: 'babel-loader', // 将babel和webpack关联
options: {
// 预设:可以将高版本JS写法转为低版本语法,例如把箭头函数转为普通函数
presets: ['@babel/preset-env'],
}
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}
只是配置预设的话,只能把高版本js写法转为低版本写法,但是对于高级API(例如:reduce、Object.assign等),是没有办法转换的。
想要转换高级API,需要用到 useBuiltIns 这个属性,其属性值有三个:
false:不需要转译(默认值)
entry:整体转译
usage:按需转译
// babel是处理js文件的
{
test: /\.js$/,
use: {
loader: 'babel-loader',
presets:[
['@babel/preset-env',{
useBuiltIns: 'usage', // 按需转译
}]
]
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}
报错:
说的是使用了 useBuiltIns 需要依赖一个包:core-js。安装完之后再进行配置
{
test: /\.js$/,
use: {
loader: 'babel-loader',
presets:[
['@babel/preset-env',{
useBuiltIns: 'usage', // 按需转译
// 使用 useBuiltIns 的时候需要安装 core-js
corejs: 3 // 查看package.json中安装的core-js是哪个版本的,需要配置一下
}]
]
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}
只是这样配置虽然实现了能转换高级API的功能,但是有一个弊端:代码中高级API使用多少次,就从core-js中引入多少次转译的模块,会造成代码的冗余。
解决这个问题:使用 @babel/plugin-transform-runtime 插件(是babel的插件)和 @babel/runtime
{
test: /\.js$/,
use: {
loader: 'babel-loader',
presets:[
['@babel/preset-env',{
useBuiltIns: 'usage', // 按需转译
// 使用 useBuiltIns 的时候需要安装 core-js
corejs: 3 // 查看package.json中安装的core-js是哪个版本的,需要配置一下
}]
],
plugins:[ // babel需要的插件
"@babel/plugin-transform-runtime", // 这个插件可以实现一次导入,多次使用,不再是使用多少次就导入多少次,减少代码冗余
]
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}
对 babel 的配置,除了可以直接配置在webapck.config.js中,还可以单独创建一个配置文件 .babelrc,将这些配置信息写在里面即可
// .babelrc 配置文件
{
"presets": [
["@babel/preset-env",{
"useBuiltIns": "usage", // 按需引入,需要安装 core-js
"corejs": 3 // 安装完 core-js 之后需要配置一下其版本
}]
],
// babel 需要的插件
"plugins": [
"@babel/plugin-transform-runtime" // 避免重复引入,减少代码冗余
]
}
// webpack.config.js 文件
{
test: /\.js/, // 匹配js文件
use: {
loader: 'babel-loader'
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}
额外再介绍一个插件: @babel/plugin-proposal-class-properties
这是插件是用来处理识别Class类的新语法的
class Person{
// a = 1; // 这是给实例添加私有属性,
// 等价于 constructor(){this.a = 1;}
constructor(){
this.a = 1;
}
b = 1; // 这种新语法webpack是不识别的,需要安装babel插件 @babel/plugin-proposal-class-properties
}
// 用babel处理js文件
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
// presets: ['@babel/preset-env'], // 这这是把高版本JS写法转为低版本写法,例如把箭头函数转为普通函数,并不能转换高级API(reduce、Object.assign等)
presets: [
[ "@babel/preset-env", {
useBuiltIns: "usage", // 按需引入
// 使用 useBuiltIns 的时候需要安装 core-js
corejs: 3 // 查看package.json中安装的core-js是哪个版本的,需要配置一下
}]
],
plugins:[ // babel需要的插件
"@babel/plugin-transform-runtime", // 这个插件可以实现一次引用,多次使用,不再是使用多少次就引用多少次
"@babel/plugin-proposal-class-properties", // 处理Class类中的属性
]
}
},
exclude: /node_modules/ // 不处理该文件夹下的js文件
}