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 工具可以这里查看