存在的问题
不同版本的浏览器能识别的ES标准并不相同,导致开发者面对不同版本的浏览器要使用不同的语言
babel
概念
Babel 是一个 JavaScript 编译器,可以把不同标准书写的语言,编译为统一的,能被各种浏览器识别的语言
由于语言转换工作灵活多样,babel的做法和postcss、webpack差不多,本身仅提供一些分析功能,真正的转换需要依托于插件完成
使用和配置
babel可以和构建工具联合使用,也可以独立使用
如果要独立使用,需要安装下面两个库
npm i @babel/core @babel/cli
使用
babel 要编译的文件 -o 编译结果文件
babel 要编译的目录 -o 编译结果目录
配置
babel本身没有做任何事情,真正的编译要依托于babel插件和babel预设来完成
如何告诉babel要使用哪些插件或预设呢,需要通过一个配置文件.babelrc
// .babelrc
{
"preset":[],
"plugins":[]
}
预设
预设是一个多个插件的集合体,用于解决一系列的常见的兼容问题
babel有多种预设,最常见的预设是@babel/preset-env
@babel/preset-env可以让你使用最新的js语法,而无需针对每种语法转换设置具体插件
配置
// .babelrc
{
"preset":["@babel/preset-env"]
}
@babel/preset-env会根据需要兼容的浏览器范围来确定如何编译,和postcss一样,可以使用.browserslistrc来描述浏览器的兼容范围
// .browserslistrc
last 3 versions
>1%
not ie<=8
@babel/preset-env自身有一些配置
预设只转换新语法,不对新的api进行任何的处理,所以需要配置useBuiltIns,它的默认值是false,表明不注入任何新的api,配置"useUbiltIns":"usage"后,会在编译碰到新的api时,从cors-js中引入新的api(core-js实现了所有的新的api),所以需要npm i core-js,碰到部分新的语法先编译成新的api,再继续编译实现的(async await),需要借助reganerator-runtime来处理。
// .babelrc
{
"preset":[
["@babel/preset-env",{
"useBuiltIns":"usage",
"corejs":3, //默认值2,设置useBuiltIns后不设置corejs,corejs版本下载的是3的,会报错
}]
]
}
插件
预设只转换正式标准,其他非正式标准的语法需要编译则通过插件来完成
预设和插件的执行顺序
- 先执行插件(从左到右)
- 后执行预设(从右到左)
{
"preset":["a","b"],
"plugins":["c","d"]
}
执行顺序:c---->d--->b---->a
在webpack中使用babel
安装
npm i babel-loader @babel/core
配置loader
// webpack.config.js
module.exports={
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:["babel-loader"]
}
]
}
}
//.babelrc
{
"presets": [["@babel/preset-env",{
"useBuiltIns":"usage",
"corejs":3
}]]
}
配置需要兼容的浏览器范围
//.browserslistrc
last 3 versions
>1%
not ie<=8