初始化项目
mkdir babel && cd babel && npm init -y
安装babel-cli
pnpm i @babel/core @babel/cli -D
- 创建src目录并创建文件
//src/test1.js const arr = [1, 2, 3]; let [a, b, ...rest] = arr;
执行babel转换
npx babel src --out-dir dist
完美,dist目录的文件原封不动,并没有被转换!!
翻翻官网,Babel's code transformations are enabled by applying plugins (or presets) to your configuration file.(Babel的代码转换是通过对配置文件应用插件(或预置)来实现的。)
- 创建babel.config.json
{
"plugins": [
["@babel/plugin-transform-block-scoping"],
["@babel/plugin-transform-destructuring",{ "useBuiltIns": true }]
]
}
安装对应的plugin
pnpm i @babel/plugin-transform-block-scoping @babel/plugin-transform-destructuring -D
再次执行命令
Perfect!!,转换成功了 const 转换成了var ,数组的解构赋值也转换成功了,但是太麻烦了,这个配置要一个一个找plugin,不完美,所以babel提供了预设presets
安装@babel/preset-env 并配置
pnpm i @babel/preset-env -D
修改babel.config.json
{
// "plugins": [
// ["@babel/plugin-transform-block-scoping"],
// ["@babel/plugin-transform-destructuring",{ "useBuiltIns": true }]
// ]
"presets": [
[
"@babel/preset-env"
]
]
}
再次执行命令,查看dist,也被转换了,这方便多了,之前转换的都是一些语法,我门转换一些新特性API(Iterator、Generator、Set、Maps)试试
const arr = [1,2,3]
let [a, b, ...rest] = arr;
const arr3 = Array.from('arrayLike')
WTF?? Array.from 并没有被转换
转换新特性API,babel6.X用的是babel-polyfill(7.x已经废弃),最新都使用core-js@3 版本,关于core-js@3
安装corejs 并继续配置@babel/preset-env
pnpm i core-js@3.27.1 -D
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns":"usage",
"corejs":"3.27.1"
}
]
]
}
执行命令查看打包结果,需要的垫片通过require加载
关于browserslist
- 现在的babel、css 转换插件都可以根据 browserslist配置文件来生成兼容目标浏览器的代码
- 在线查看浏览器覆盖率
- 本地查看覆盖的浏览器
pnpm i browserslist -D
npx browserslist
4. 相关资料
Speed up with Browserslist
接下来配置browserlist,直接在跟文件下创建.browserslistrc,什么都不写会默认不使用browserlist,defaults相当于[> 0.5%, last 2 versions, Firefox ESR, not dead]
在配置只配置defaults,继续打包,看到打包后的文件又不会转换了,证明目前使用的es6默认配置覆盖的浏览器是支持的,生产中有一些配置可以加上,比如ios版本的要求
//.browserslistrc
defaults
ios >= 7
再次打包,不支持的一些helper会再次加载进来
runtime
在测试文件里再加入一些async、promise
function sleep(m){
return new Promise(resolve => {
setTimeout(resolve,m * 1000,true)
})
}
async function point(){
console.log('start');
await sleep(3)
console.log('end')
}
point()
再次打包可以看到async 并不想其他es6一样直接require一个helper函数,而是直接注入的,这就有一个问题如果项目很多文件helper直接注入就会导致包很大,babel提供了解决方案@babel/plugin-transform-runtime
// 安装 @babel/plugin-transform-runtime
pnpm i @babel/plugin-transform-runtime -D
// @babel/runtime 要安装生产依赖
pnpm i @babel/runtime -S
// 修改babel配置文件
{
"presets": [
[
"@babel/preset-env"
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",{
"corejs":3
}
]
]
}
打包后async的helper不是直接注入了,而且也不会直接require辅助函数到全局。这里需要注意的是corejs 在@babel/preset-env跟@babel/plugin-transform-runtime都可以配置,当使用babel/plugin-transform-runtime配置corejs后@babel/preset-env就不需要配置,可以试着分别设置corejs 查看打包产物
最后一个点
babel 打包出来的不能直接运行在浏览器,只能运行在node,运行浏览器需要借助webpack等打包工具把helper函数打包进生成的文件里
- 推荐阅读
Babel浅谈