babel的安装和使用 {ignore}
> 官网:https://babeljs.io/
> 民间中文网:https://www.babeljs.cn/
## babel简介 babel一词来自于希伯来语,直译为巴别塔
巴别塔象征的统一的国度、统一的语言;而今天的JS世界缺少一座巴别塔,不同版本的浏览器能识别的ES标准并不相同,就导致了开发者面对不同版本的浏览器要使用不同的语言,和古巴比伦一样,前端开发也面临着这样的困境。babel的出现,就是用于解决这样的问题,它是一个编译器,可以把不同标准书写的语言,编译为统一的、能被各种浏览器识别的语言
由于语言的转换工作灵活多样,babel的做法和postcss、webpack差不多,它本身仅提供一些分析功能,真正的转换需要依托于插件完成
## babel的安装
babel可以和构建工具联合使用,也可以独立使用;如果要独立的使用babel,需要安装下面两个库:
- @babel/core:babel核心库,提供了编译所需的所有api
- @babel/cli:提供一个命令行工具,调用核心库的api完成编译shell<br />**npm i -D @babel/core @babel/cli**<br />
## babel的使用
@babel/cli的使用极其简单;它提供了一个命令**babel**
```shell
# 按文件编译
例如:npx babel js/a.js -o js/b.js
babel 要编译的文件 -o 编辑结果文件
# 按目录编译
例如:npx babel js -o dist
babel 要编译的整个目录 -d 编译结果放置的目录<br />**## babel的配置**<br />可以看到,babel本身没有做任何事情,真正的编译要依托于****babel插件****和****babel预设****来完成;> babel预设和postcss预设含义一样,是多个插件的集合体,用于解决一系列常见的兼容问题;如何告诉babel要使用哪些插件或预设呢?需要通过一个配置文件`**.babelrc`**<br />
json
{
“presets”: [],
“plugins”: []
}<br />**babel预设**<br />babel有多种预设,最常见的预设是`**@babel/preset-env`**<br />`**@babel/preset-env`**可以让你使用最新的JS语法,而无需针对每种语法转换设置具体的插件 **npm i -D @bable/preset-env **<br />****配置****<br />
json
{
“presets”: [
“@babel/preset-env”
]
}<br />****兼容的浏览器****<br />`**@babel/preset-env`**需要根据兼容的浏览器范围来确定如何编译,和postcss一样,可以使用文件`**.browserslistrc**`来描述浏览器的兼容范围<br />
last 3 version
> 1%
not ie <= 8<br />****自身的配置****<br />和`postcss-preset-env`一样,`@babel/preset-env`自身也有一些配置<br />> 具体的配置见:[https://www.babeljs.cn/docs/babel-preset-env#options](https://www.babeljs.cn/docs/babel-preset-env#options)<br />配置方式是:<br />
json
{
“presets”: [
[“@babel/preset-env”, {
“配置项1”: “配置值”,
“配置项2”: “配置值”,
“配置项3”: “配置值”
}]
]
}<br />其中一个比较常见的配置项是**`usebuiltins**`,该配置的默认值是false;<br />它有什么用呢?由于该预设仅转换新的语法,并不对新的API进行任何处理<br />例如:<br />
js
new Promise(resolve => {
resolve()
})<br />转换的结果为<br />
js
new Promise(function (resolve) {
resolve();
});<br />如果遇到没有Promise构造函数的旧版本浏览器,该代码就会报错;而配置**`****useBu****iltins`**可以在编译结果中注入这些新的API,它的值默认为`false`,表示不注入任何新的API。设置为`usage`,表示根据API的使用情况,按需导入API ;导入之后需要下载 **npm i core-js**;然后要设置"**corejs":3**; 还有**npm i regenerator-runtime**<br />
json
{
“presets”: [
[“@babel/preset-env”, {
“useBuiltIns”: “usage”,
“corejs”: 3
}]
]
}<br />**babel插件 {ignore}**<br />@babel/polyfill 已过时,目前被`core-js`和`generator-runtime`所取代;<br />除了预设可以转换代码之外,插件也可以转换代码,它们的顺序是:<br />- 插件在 Presets 前运行。<br />- 插件顺序从前往后排列。<br />- Preset 顺序是颠倒的(从后往前)。<br />通常情况下,`@babel/preset-env`只转换那些已经形成正式标准的语法,对于某些处于早期阶段、还没有确定的语法不做转换。<br />如果要转换这些语法,就要单独使用插件;下面随便列举一些插件<br />**## `@babel/plugin-proposal-class-properties`**<br />该插件可以让你在类中书写初始化字段<br />
js
class A {
a = 1;
constructor(){
this.b = 3;
}
}<br />**## `@babel/plugin-proposal-function-bind`**<br />该插件可以让你轻松的为某个方法绑定this<br />
js
function Print() {
console.log(this.loginId);
}
const obj = {
loginId: “abc”
};
obj::Print(); //相当于:Print.call(obj);<br />遗憾的是,目前vscode无法识别该语法,会在代码中报错,虽然并不会有什么实际性的危害,但是影响观感;<br />**## `@babel/plugin-proposal-optional-chaining`**<br />
js
const obj = {
foo: {
bar: {
baz: 42,
},
},
};
const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined``<br />**##
babel-plugin-transform-remove-console`**
该插件会移除源码中的控制台输出语句
js<br />**console.log("foo");**<br />**console.error("bar");**<br />
编译后
```<br />**## `@babel/plugin-transform-runtime`**
用于提供一些公共的API,这些API会帮助代码转换
```css
package.json---
"scripts": {
"build": "babel js -o dist -w"
},
.browserslistrc---
last 3 version
> 1%
not ie <= 8
.babelrc---
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
],
"plugins": [
["@babel/proposal-class-properties", {
"loose": true
}],
"@babel/proposal-function-bind",
"@babel/proposal-optional-chaining",
"transform-remove-console",
"@babel/transform-runtime"
]
}
在webpack中使用babel
webpack.config.js---
module.exports = {
mode: "development",
devtool: "source-map",
module: {
rules: [
{ test: /\.js$/, use: "babel-loader" }
]
}
}
.browserslistrc---
last 3 version
> 1%
not ie <= 8
.babelrc---
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
./src/index.js---
const func = () => {
console.log("abc");
}
func();
new Promise(resolve => {
resolve();
})
async function method(){
}
/* 和webpack的结合,和postcss类似。是要添加一个loader,babel-loader*/