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