Babel-抽象语法树

前言

Babel插件就是作用于抽象语法树。

首先我们编写的代码在编译阶段解析成抽象语法树(AST),然后经过一系列的遍历和转换,然后再将转换后的抽象语法树生成为常规的js代码。

img

介绍

AST可以方便计算机更好地理解我们的代码

它是Babel 转译的核心数据结构,后续的操作都依赖于 AST

举个例子:

1
2
3
4
5
function add(x, y) {
return x + y;
}

add(1, 2);

通过一个AST Explorer 在线工具,我们把代码转换成 AST

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
"type": "Program", // 程序
"start": 0,
"end": 53,
"body": [
{
"type": "FunctionDeclaration", // 方法声明
"start": 0,
"end": 40,
"id": {
"type": "Identifier", // 标识符
"start": 9,
"end": 12,
"name": "add"
},
"expression": false,
"generator": false,
"async": false,
"params": [
{
"type": "Identifier", // 标识符
"start": 13,
"end": 14,
"name": "x"
},
{
"type": "Identifier", // 标识符
"start": 16,
"end": 17,
"name": "y"
}
],
"body": {
"type": "BlockStatement", // 区块语句
"start": 19,
"end": 40,
"body": [
{
"type": "ReturnStatement", // 返回声明
"start": 25,
"end": 38,
"argument": {
"type": "BinaryExpression", // 二进制表达式
"start": 32,
"end": 37,
"left": {
"type": "Identifier", // 标识符
"start": 32,
"end": 33,
"name": "x"
},
"operator": "+",
"right": {
"type": "Identifier", // 标识符
"start": 36,
"end": 37,
"name": "y"
}
}
}
]
}
},
{
"type": "ExpressionStatement", // 表达式语句
"start": 42,
"end": 52,
"expression": {
"type": "CallExpression", // 调用表达式
"start": 42,
"end": 51,
"callee": {
"type": "Identifier", // 标识符
"start": 42,
"end": 45,
"name": "add"
},
"arguments": [
{
"type": "Literal", // 字面量
"start": 46,
"end": 47,
"value": 1,
"raw": "1"
},
{
"type": "Literal", // 字面量
"start": 49,
"end": 50,
"value": 2,
"raw": "2"
}
],
"optional": false
}
}
],
"sourceType": "module" // 模块
}

可以发现抽象语法树中不同层级有着相似的结构,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"type": "Program", // 程序
"start": 0,
"end": 52,
"body": [...]
}
{
"type": "FunctionDeclaration", // 方法声明
"start": 0,
"end": 40,
"id": {...},
"body": {...}
}
{
"type": "BlockStatement", // 区块语句
"start": 19,
"end": 40,
"body": [...]
}

像这样的结构叫做节点(Node)。一个AST是由多个或单个这样的节点组成,节点内部可以有多个这样的子节点,构成一颗语法树,这样就可以描述用于静态分析的程序语法。

节点中的type字段表示节点的类型,比如上述AST中的”Program”、”FunctionDeclaration”、”ExpressionStatement”等等,当然每种节点类型会有一些附加的属性用于进一步描述该节点类型。

除了类型属性,还额外生成了位置属性、值属性等,更好的描述每个节点。

参考文章

深入Babel,这一篇就够了