什么是AST?
AST 就是把你的代码,翻译成“机器能读懂的目录结构”
你写代码时写的是字符串(String),比如:
const name = "Gemini";
对于电脑来说,这只是一串字符。为了理解它,电脑需要像我们在语文课上做“主谓宾”分析一样,把它拆解开:
const 是声明(像动词)
name 是变量名(像名词)
= 是操作符
"Gemini" 是值(字符串)
把这些成分按照层级关系挂在一棵树上,就是 AST。
AST怎么生成的?
第一步:词法分析 (Lexical Analysis) —— 分词
就像把一篇文章切分成一个个单词。编译器会把代码字符串切割成一个个最小单位,叫做 Token(词法单元)。
代码:
JavaScript
const a = 1;
切分后的 Tokens(数组):
const (关键字)
a (标识符)
= (赋值符号)
1 (数字字面量)
第二步:语法分析 (Syntactic Analysis) —— 建树
把上面的 Tokens 按照语法规则,拼装成一个树状结构。
AST 结构(简化版 JSON 表示):
JSON
{
"type": "Program", // 根节点
"body": [
{
"type": "VariableDeclaration", // 变量声明语句
"kind": "const", // 类型是 const
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier", // 标识符
"name": "a" // 名字是 a
},
"init": {
"type": "Literal", // 字面量
"value": 1, // 值是 1
"raw": "1"
}
}
]
}
]
}
代码里的空格、分号、括号都不见了(所以叫“抽象”),只留下了核心逻辑结构(所以叫“语法树”)。
为什么 Tree Shaking 必须依赖 AST?
有了 AST,工具就能开启“上帝视角”:
- 扫描: 它遍历这棵树,看到
import { A } from './utils',就在 AST 节点上打个标:“引入了 A”。
- 追踪: 它接着看后面的 AST 节点,发现从头到尾只有
console.log(B),并没有任何节点用到变量 A。
- 摇树: 既然 AST 告诉我变量
A 的节点虽然被引入了,但没有被任何后续节点引用(Reference),那这段 AST 分支就可以被剪掉。
- 生成: 最后把修剪好的 AST 重新变回代码字符串(这个过程叫
generate)。
AST的其他应用
AST 是前端工程化的基石。除了 Tree Shaking,你每天用的工具都在用 AST:
- Babel: 把 ES6 的 AST 转换成 ES5 的 AST,再生成代码(这就叫转译)。
- ESLint: 遍历 AST,发现有一个节点的类型是
VariableDeclaration 且用了 var,就报错“请使用 let/const”。
- Prettier: 不管你代码写得多乱,它先解析成 AST,然后按照标准的缩进规则重新生成代码,格式就变好看了。
- Vue/React 模板编译: 把
<div v-if="..."> 变成 AST,然后转换成 JavaScript 的渲染函数(Render Function)。
总结
AST 就是代码的“骨架”。Vite (Rollup) 通过分析这副骨架,精准地剔除掉了多余的骨头(无用代码),这就是 Tree Shaking 的本质。
Life's a struggle, I'll conquer it.