webpack
和Lint
等不少的工具和库的核心都是经过Abstract Syntax Tree
抽象语法树这个概念来实现对代码的检查、分析等操做的node
这些工具的原理都是经过JavaScript Parser
把代码转化为一颗抽象语法树(AST),这颗树定义了代码的结构,经过操纵这颗树,咱们能够精准的定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变动等操做webpack
在计算机科学中,抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。web
Javascript的语法是为了给开发者更好的编程而设计的,可是不适合程序的理解。因此须要转化为AST来使之更适合程序分析,浏览器编译器通常会把源码转化为AST来进行进一步的分析等其余操做。 JavaScript Parserexpress
JavaScript Parser,把js源码转化为抽象语法树的解析器。npm
浏览器会把js源码经过解析器转为抽象语法树,再进一步转化为字节码或直接生成机器码。编程
通常来讲每一个js引擎都会有本身的抽象语法树格式,Chrome的v8引擎,firefox的SpiderMonkey引擎等等,MDN提供了详细SpiderMonkey AST format的详细说明,算是业界的标准。浏览器
接下来咱们将下面代码转换成AST,而后生成先的函数newAstbash
let code = 'function ast(){}'; //js代码便可(字符串形式)async
esprima
estraverse
escodegen
npm i esprima estraverse escodegen -D
复制代码
把上面的源码转成AST编程语言
// 把源码转化为AST
let ast = esprima.parseModule(code);
console.log(ast);
复制代码
打印结果以下 Module { type: 'Program', body: [ FunctionDeclaration { type: 'FunctionDeclaration', id: [Object], params: [], body: [Object], generator: false, expression: false, async: false } ], sourceType: 'module' }
复制代码
let indent = 0;
function padding() {
return " ".repeat(indent);
}
estraverse.traverse(ast, {
enter(node) {
//进入
console.log(padding() + node.type + "进入");
if (node.type === "FunctionDeclaration") {
node.id.name = "newAst";
}
indent += 2;
},
leave(node) {
//离开
indent -= 2;
console.log(padding() + node.type + "退出");
},
});
复制代码
打印结果
Program进入
FunctionDeclaration进入
Identifier进入
Identifier退出
BlockStatement进入
BlockStatement退出
FunctionDeclaration退出
Program退出
复制代码
最后,把修改后的抽象语法从新生成源代码
//把修改事后的抽象语法树从新生成源代码
let result = escodegen.generate(ast);
console.log(result);
复制代码
打印后的结果
function newAst() {
}
复制代码