Javascript AST语法树简介
什么是 AST
- 抽象语法树(Abstract Syntax Tree):把源代码解析成的一棵树状结构,节点代表语法结构(变量、函数、表达式等)。
- 比源代码更结构化,去掉了空白和注释,便于静态分析、代码转换和生成。
为什么需要 AST
- 代码静态分析(lint、类型检查)
- 代码转换(Babel、编译、polyfill)
- 代码重构、自动化修改
- 代码生成(代码格式化、压缩、打包)
规范与格式
- 常用格式:ESTree(多数 JS 解析器遵循)
- 节点包含 type、start/end(位置)、具体字段(id、params、body 等)
常用解析器/工具
- @babel/parser(Babel) — 支持最新语法、插件丰富
- Esprima — 轻量、ESTree 兼容
- Acorn — 快速、可扩展
- @babel/traverse、estraverse — 遍历/修改 AST
- @babel/generator / recast — 从 AST 生成代码
常见节点(示例)
- Program, VariableDeclaration, VariableDeclarator
- FunctionDeclaration, ArrowFunctionExpression
- Identifier, Literal
- ExpressionStatement, CallExpression, MemberExpression
- BinaryExpression, ReturnStatement, IfStatement, ForStatement, BlockStatement
简单示例:原始代码 -> AST(部分)
原始代码:
const x = 1 + 2;
function f(a){ return a * 2; }
对应的 AST(简化示意,JSON 形式 JSON解析):
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"kind": "const",
"declarations": [
{
"type": "VariableDeclarator",
"id": { "type": "Identifier", "name": "x" },
"init": {
"type": "BinaryExpression",
"operator": "+",
"left": { "type": "Literal", "value": 1 },
"right": { "type": "Literal", "value": 2 }
}
}
]
},
{
"type": "FunctionDeclaration",
"id": { "type": "Identifier", "name": "f" },
"params": [{ "type": "Identifier", "name": "a" }],
"body": {
"type": "BlockStatement",
"body": [
{ "type": "ReturnStatement", "argument": { "type": "BinaryExpression", "operator": "*", "left": { "type": "Identifier", "name": "a" }, "right": { "type": "Literal", "value": 2 } } }
]
}
}
]
}
使用 Babel 做解析、遍历、生成(最小示例)
在 mac 终端:
npm install @babel/parser @babel/traverse @babel/generator
示例代码(Node.js):
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;
const code = `const x = 1 + 2; function f(a){ return a * 2; }`;
const ast = parser.parse(code, { sourceType: "module" });
// 遍历:把所有数字常量加 1
traverse(ast, {
NumericLiteral(path) {
path.node.value += 1;
}
});
const output = generator(ast).code;
console.log(output); // const x = 2 + 3; function f(a) { return a * 3; }
实践建议
- 优先用 Babel 或 Acorn 解析复杂现代语法
- 使用 traverse/estraverse 做遍历和修改,generator/recast 生成代码
- 熟悉 ESTree 节点类型和常见模式匹配(如 CallExpression、Identifier 等)
参考
- ESTree 规范
- @babel/parser / @babel/traverse / @babel/generator 文档
- Esprima / Acorn 项目页
如需示例扩展(特定转换、插件写法或工具链集成),说明具体场景。
浙公网安备 33010602011771号