Babel基础知识
1. 介绍
1.1 简介
Babel 是一个 JavaScript 编译器。
Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
Babel是一个工具集,主要用于将ES6版本的JavaScript代码转为ES5等向后兼容的JS代码,从而可以运行在低版本浏览器或其它环境中
比如:我们在代码中使用了ES6箭头函数
// 编译前
var fn = (num) => num + 2;
但如果是运行在一些低版本的浏览器里面,就会报错;经过Babel编译之后的代码就可以运行在IE11以及更低版本的浏览器中了
// 编译后
var fn = function fn(num) {
return num + 2;
}
Babel就是做了这样的编译转换工作,来让我们不用考虑浏览器的兼容性问题,只要专心于代码的编写工作
1.2 历史
babel5及之前是一个包含CLI工具+编译器+转换器的集合工具包;babel6之后进行了拆分,集合包被分成多个包
- babel-cli,Babel命令行转码工具,如果我们使用命令行进行Babel转码就需要安装它
- babel-core,包括了Node有关的API和require钩子
- babel-polyfill,可以建立一个完整的ES2015环境
babel6默认情况下不携带任何转换器,需要自行安装所需的插件和转换器,通过babel-xxx
来安装对应的工具包。
而Babel7用了npm的private scope,把所有的包都挂载@babel
下,通过@babel/xxx
来安装,不用在node_modules下看到一堆的babel-xxx包
1.3 @Babel/core
和 Babel/cli
1.3.1 @Babel/core
@babel/core我们在很多地方都看到,它是Babel进行转码的核心依赖包,我们常用的babel-cli和babel-node都依赖于它。
Babel的运行方式总共可以分为三个阶段:解析(parsing)、转换(transforming)和生成(generating);负责解析阶段的插件是@babel/parser
,其作用就是将源码解析成AST;而负责生成阶段的插件是@babel/generator
,其作用就是将转好好的AST重新生成代码。
而@babel/core本身不具备转换处理的功能,它把转换的功能拆分到一个个插件(plugins)中;因此当我们不添加任何插件的时候,输入输出代码是相同的
1.3.2 @babel/cli
@babel/cli
是Babel自带了一个内置的CLI命令行工具,我们就可以通过命令行来编译文件;它有两种调用方式,可以通过全局安装或者本地安装调用,选用一种即可,推荐在项目本地安装
// 全局安装调用
npm install --g @babel/cli
babel index.js -o output.js
// 本地安装调用
npm install --save-dev @babel/cli
npx babel index.js -o output.js
可以使用以下命令参
1.3.3 babel-cli基本用法
# 转码结果输出到标准输出
$ babel example.js
# 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
$ babel example.js --out-file compiled.js
# 或者
$ babel example.js -o compiled.js
# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
$ babel src --out-dir lib
# 或者
$ babel src -d lib
# -s 参数生成source map文件
$ babel src -d lib -s
1.4 配置文件
虽然可以在命令行中配置各种插件(plugins)或者预设,但是这样就不利于管理和维护,因此Babel推荐通过配置文件的方式来进行管理。
Babel的配置文件主要有.babelrc
、.babelrc.js
、babel.config.js
和package.json
,他们的配置选项都是相同的,作用也是一样,主要区别在于格式语法的不同,因此我们在项目中只需要选择其中一种即可
1.4.1 .babelrc
配置:
可以在配置文件中加入一些插件或者预设,来扩展@babel/core的转换功能;只需要将对应的插件或预设名字加入数组即可
比如我们常用的ES6箭头函数,就是通过@babel/plugin-transform-arrow-functions
这个插件来转换
{
"presets": [...],
"plugins": ["@babel/plugin-transform-arrow-functions"]
}
如果需要对插件和预设设置参数,即是如下的格式
//.babelrc
{
"plugins": [
[
"@babel/plugin-transform-arrow-functions",
{ "spec": true }
]
]
}
spec属性
这个属性主要是给其他插件传递参数(比如@babel/plugin-transform-arrow-functions),默认是false,设为true后,箭头函数会有以下改变:
- 将箭头函数生成的函数用
.bind(this)
包裹一下,以便在函数内部继续使用this,而不是重命名this。 - 加一个检查防止函数被实例化
- 给箭头函数加一个名字
1.4.2 .babelrc.js
和babel.config.js
的配置
同样都是JS语法,通过module.exports的方式输出配置
module.exports = function (api) {
api.cache(true);
const presets = [ ... ];
const plugins = [ ... ];
if (process.env["ENV"] === "prod") {
plugins.push(...);
}
return {
presets,
plugins
};
}
1.4.3 package.json
配置
增加babel
的属性即可
{
"name": "demo",
"version": "1.0.0",
"babel": {
"presets": [ ... ],
"plugins": [ ... ],
}
}
1.4.4 babel.config.json
配置(Babel7推荐)
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"ie": "10", // 最低兼容ie10浏览器
"edge": "11",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage" // 按需加载
}
]
],
"plugins": [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-object-assign"
]
}
targets属性
targets主要是用来描述我们在项目中想要支持的目标浏览器环境,它可以是Browserslist格式的查询
{
"targets": "> 0.25%, not dead"
}
或者可以是一个对象,用来描述支持的最低版本的浏览器:
{
"targets": {
"chrome": "58",
"ie": "11"
}
}
其他的浏览器版本还可以是:opera
、edge
、firefox
、safari
、ios
、android
、node
、electron
等
1.5 Babel插件和预设
Babel的插件大致可以分为语法插件
和转换插件
:
- 语法插件:作用于解析阶段,使得babel能够解析更多的语法,官方的语法插件以
babel-plugin-syntax
开头 - 转换插件:在转换这一步把源码转换并输出,官方的转换插件以
babel-plugin-transform
(正式)或 babel-plugin-proposal
(提案)开头
2. 使用
2.1 方式一:引入第三方js(一般不推荐使用)
<!--1 引入browser.min.js文件 -->
<!--注意:browser.min.js IE9以下本身就不支持-->
<script type="text/javascript" src="browser.min.js"></script>
<!--2. 设置script类型: type="text/babel" -->
<script type="text/babel">
let a = [1, 2, 3];
console.log(a);
const show = name => console.log(name);
show('你好呀');
</script>
2.2 方法二:Babel命令编译
2.2.1 初始化项目
自动生成一个 package.json
包
npm init -y
2.2.2 安装babel项目依赖
npm i -D @babel/core @babel/cli @babel/preset-env
以下项目包是根据根据需要安装使用
可以兼容更低版本的浏览器,比如IE等更低
npm install --save @babel/polyfill
单独安装箭头函数转换的插件(可以安装、也可以不安装,如果不安装,就可以使用babel的预设项)
npm install --save-dev @babel/plugin-transform-arrow-functions
2.2.3 babel
配置文件
新建一个 babel
配置文件:babel.config.json
,主要是进行babel预设的配置
{
"presets": [
[
"@babel/env",
{
"targets": {
"ie":"10", //这个是自己添加的,最好是加上
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage" // 按需加载
}
]
]
"plugins": [
"@babel/plugin-transform-member-expression-literals",
"@babel/plugin-transform-property-literals"
]
}
2.2.4 创建npm命令
在package.json中创建快捷执行命令
"scripts": {
"dev": "babel src --out-dir src --minified --ignore 'src/*.min.js,src/**/*.min.js,src/**/**/*.min.js' --out-file-extension .min.js"
// 这个是执行箭头函数转换的命令
"build-arrow": "babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions"
},
--minified:压缩混淆
--ignore:忽略某些文件
--out-file-extension .min.js :设置文件扩展名
更多配置参考:https://www.babeljs.cn/docs/babel-cli#安装
2.2.5 命令执行
npm run build
在phpstrom中的配置
$FilePathRelativeToProjectRoot$ --out-dir $FileDirRelativeToProjectRoot$ --minified --presets @babel/env --ignore "template/wap/skin/**/*.min.js,template/wap/skin/**/**/*.min.js" --out-file-extension .min.js"