Babel
Babel是什么
-
Babel 是一个 JavaScript 编译器。
-
Babel 通过语法转换器支持最新版本的 JavaScript
-
为了能在现有的浏览器上使用js新的语法和新的数据类型,就需要使用一个转译器,将javascript中新增的特性转为浏览器能理解的形式。babel就是做这个方面的转化工作
Babel 家族成员及其能力和实现原理
-
@babel/plugin是 Babel 插件集合。
-
@babel/plugin-syntax-* 是 Babel 的语法插件。它的作用是扩展 @babel/parser 的一些能力,提供给工程使用。比如 @babel/plugin-syntax-top-level-await 插件,提供了使用 top level await 新特性的能力。
-
@babel/plugin-proposal-* 用于编译转换在提议阶段的语言特性。
-
@babel/plugin-transform-* 是 Babel 的转换插件。比如简单的 @babel/plugin-transform-react-display-name 插件,可以自动适配 React 组件 DisplayName,比如:
-
@babel/template 封装了基于 AST 的模板能力,可以将字符串代码转换为 AST。比如在生成一些辅助代码(helper)时会用到这个库。
-
@babel/node 类似 Node.js Cli,@babel/node 提供在命令行执行高级语法的环境,也就是说,相比于 Node.js Cli,它加入了对更多特性的支持。
-
@babel/register 实际上是为 require 增加了一个 hook,使用之后,所有被 Node.js 引用的文件都会先被 Babel 转码。
这里请注意@babel/node 和 @babel/register,都是在运行时进行编译转换,因此运行时性能上会有影响。在生产环境中,我们一般不直接使用。
-
@babel/preset-env:包含比较新的ES语法 ,es6+转es5的转换规则
-
@babel/core:这个库负责解析,方便各个插件分析语法进行相应的处理
-
@babel-polyfill: 把es的新特性都装进来,来弥补低版本浏览器器中缺失的特性
安装Babel
npm install --save-dev @babel/core @babel/cli @babel/preset-env
@babel/preset-env:包含比较新的ES语法 ,es6+转es5的转换规则
@babel/core:这个库负责解析,方便各个插件分析语法进行相应的处理
@babel-polyfill: 把es的新特性都装进来,来弥补低版本浏览器器中缺失的特性
为什么会有Babel存在
原因是javascript在不断的发展,但是浏览器的发展速度跟不上。以es6为例,es6中为javascript增加了箭头函数、块级作用域等新的语法和Symbol、Promise等新的数据类型,但是这些语法和数据类型并不能够马上被现在的浏览器全部支持,
babel的两套包
- 第一套包:相当于是转换器,转换语法
- 第二套包:babel-preset-env 是比较新的ES语法,包含了ES相关的语法
第一套包:yarn add -D babel-core babel-loader babel-plugin-transform-runtime
第二套包:yarn add -D babel-preset-env babel-preset-stage-0
Babel 是如何工作的 【原理】
Babel 的三个主要处理步骤分别是: 解析(parse),转换(transform),生成(generate)
- 解析: 代码在编译阶段解析成抽象语法树(AST)
- @babel/parser来帮助我们分析内部的语法. 返回一个AST抽象语法树
在解析过程中有两个阶段:词法分析和语法分析
- 词法分析阶段把代码转换为令牌(tokens)流
- 语法分析阶段则会把一个令牌流转换成 AST的形式
- 转换: 然后经过一系列的遍历和转换抽象语法树
- @babel/traverse 可以用来遍历@babel/parser生成的AST
- 生成: 以新的 抽象语法树AST 生成js代码
- 借助@babel/core (负责解析)、@babel/preset-env (转换js语法)
解析
将代码解析成抽象语法树(AST),每个js引擎(比如Chrome浏览器中的V8引擎)都有自己的AST解析器,而Babel是通过Babylon实现的。在解析过程中有两个阶段:词法分析和语法分析,词法分析阶段把字符串形式的代码转换为令牌(tokens)流,令牌类似于AST中节点;而语法分析阶段则会把一个令牌流转换成 AST的形式,同时这个阶段会把令牌中的信息转换成AST的表述结构。
转换
在这个阶段,Babel接受得到AST并通过babel-traverse对其进行深度优先遍历,在此过程中对节点进行添加、更新及移除操作。这部分也是Babel插件介入工作的部分。
生成
将经过转换的AST通过babel-generator再转换成js代码,过程就是深度优先遍历整个AST,然后构建可以表示转换后代码的字符串
了解 Babel parse AST 的过程
在解析成 AST 过程中有两个阶段:词法分析和语法分析。
词法分析: 也叫scanner(扫描器),它读取我们的source code(源代码)中每一个字符,转换成token流(词法令牌),令牌类似于AST中的节点
语法分析:也叫parser(解析器),将词法分析器解析出的令牌流,转换成AST的形式,同时把令牌中的信息转化为AST的表述结构。
AST 遍历的过程
Babel 在处理一个节点时,是以访问者(Visitor)的形式获取节点信息并进行相关操作。这种方式是通过 Visitor 对象来完成的,Visitor 对象中定义了对于各种节点的访问函数,这样就可以针对不同的节点做出不同的处理