AST 是什么

AST 是抽象语法树(Abstract Syntax Tree)的缩写,抽象语法树是一种数据结构,用来代表程序的结构,目前流行的 babel 转换 es6 代码也是使用抽象语法树来实现的,最直观的图示

AST 能做什么

除了 es6 的语法转换,node 和浏览器执行 js 代码,uglify 模块压缩代码等等,都是通过 ast 来实现的

目前比较流行的转换 ast 的模块有 esprima 和 acorn,下面使用 esprima 来研究一下

const esprima = require('esprima');
let ast = esprima.parse('let name="kelen"');

上面利用 esprima 来把 js 代码let name="kelen"转为 ast,结果如下

{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": { "type": "Identifier", "name": "name" },
"init": { "type": "Literal", "value": "kelen", "raw": "\"kelen\"" }
}
],
"kind": "let"
}
],
"sourceType": "script"
}

转换成 ast 后可以用,我们可以使用 estraverse 来遍历这个对象修改,移除,新增节点等等,然后利用 escodegen 来将转换后的 ast 还原成转换后的 js 代码

es6 转 es5

下面尝试把 es6 语法let name="kelen"转换为var a = "kelen",是不是类似于 babel 转换 es6,嘿嘿嘿~

const esprima = require('esprima');
const estraverse = require('estraverse');
const escodegen = require('escodegen');
let ast = esprima.parse('let name = "kelen"');
estraverse.traverse(ast, {
enter(node, parent) {
if (node.type == 'Identifier' && node.name == 'name') {
node.name = 'n';
return node;
}
if (node.type === 'VariableDeclaration' && node.kind == 'let') {
node.kind = 'var';
return node;
}
},
});
var js = escodegen.generate(ast);
console.log(js); // var n = "kelen"

更多的ECMAScript 工具可以这里查看