AST是AbstractSyntaxTree的缩写,即“抽象语法树”。它以树的形式表达了编程语言的语法结构。webpack打包JS代码的时候,webpack会在我们原有代码的基础上添加一些代码,比如我们在打包JS代码的时候可以将高层代码转化为低层代码,即通过AST语法树来完成AST在线生成地址babel插件查看和使用地址抽象语法树如leta=1+2词法分析从左到右一个字符一个字符地读取源程序,一个一个识别“单词”和“符号”并读出普通字符,无需任何编程语言函数将分析结果保存在一个词汇单元数组wordwordsymbolnumbersymbolnumberleta=1+2[{"type":"word",value:"let"},{"type":"word",value:"a"},{"type":"Punctuator",value:"="},{"type":"Numberic",value:"1"},{"type":"Punctuator",value:"+"},{"type":"Numberic",value:"2"},]然后进入词法分析语法分析将单词序列组合成各种语法短语关键字标识符赋值运算符Literalbinaryoperations字符字面量leta=1+2[{"type":"VariableDecLation","content":{{"type":"kind","value":"let"},//kind表示声明的类型{"type":"Identifier","value":"a"},//Identifier表示一个标识符{"type":"init","value":"="},//表示初始的表达式valueFormula{"type":"Literal","value":"1"},//Literal表示它是一个文字{"type":"operator","value":"+"},//operator表示它是一个二元运算符{"type":"Literal","value":"2"},}}]抽象语法树"program":{"type":"Program","start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},"sourceType":“模块”,“解释器”:空,“主体”:[{“类型”:“VariableDeclaration","start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},"declarations":[//这里是一个数组,表示可以同时声明多个变量{"type":"VariableDeclarator","start":4,"end":13,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":13}},"id":{"type":"标识符","开始":4,"结束":5,“loc”:{“开始”:{“行”:1,“列”:4},“结束”:{“行”:1,“列”:5},“identifierName”:“a”},"name":"a"},"init":{"type":"BinaryExpression","start":8,"end":13,"loc":{"start":{"line":1,“列”:8},“结束”:{“行”:1,“列”:13}},“左”:{“类型”:“NumericLiteral","start":8,"end":9,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":9}},"extra":{"rawValue":1,"raw":"1"},"value":1},"operator":"+","right":{"type":"NumericLiteral","start":12,"end":13,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":13}},"extra":{"rawValue":2,"raw":"2"},"value":2}}}],"kind":"let"}],"directives":[]}程序示例package.json依赖"@babel/generator":"^7.11.6",//转换AST结构"@babel/parser":"^7.11.5",//反汇编AST树结构"@babel/traverse":"^7.11.5","@babel/types":"^7.11.5",@babel/parsegeneratesASTimport*asparserfrom'@babel/parser'constcode=`leta=1+2`constast=parser.parse(code)console.log(ast)通过babel的遍历模块修改语法树遍历节点,找到对应节点后,将babel中的generator传入ator模块将语法树转换为代码import*asparserfrom'@babel/parser'importtraversefrom"@babel/traverse"importgeneratorfrom'@babel/generator'constcode=`letval=1+2`constast=parser.parse(code)console.log(ast)//遍历方法可以遍历所有语法树节点traverse(ast,{enter(path){//这个路径会找到所有节点if(path.node.type=='Identifier'){path.node.name='modify'path.stop()}}})constret=generator(ast)console.log(ret)这里会修改val来修改创建语法树通过@babel/types模块创建一个语法树节点,然后将其推入主体以手动创建语法树,import*asparserfrom'@babel/parser'importtraversefrom"@babel/traverse"importgeneratorfrom'@babel/generator'import*astfrom'@babel/types'letcode=``letast=parser.parse(code)letleft=t.NumericLiteral(1)letright=t.NumericLiteral(2)letinit=吨。binaryExpression("+",left,right)letid=t.identifier("add")letvariable=t.variableDeclarator(id,init)letdeclaration=t.variableDeclaration('let',[variable])ast.program.body.push(declaration)//转为codeletgenCode=generator(ast)console.log(genCode.code)deletesyntaxtreenode想要删除语法节点的核心是遍历到查找所有节点由@babel/traverse完成。找到每个节点后,可以通过具体的方法完成增删改查操作节点findParent:从父节点中搜索节点getSibling:获取兄弟节点replaceWith:用AST节点替换此节点replaceWithMultiple:用多个AST节点替换此节点insertBefore:在节点之前插入一个节点insertAfter:在插入节点之后插入节点移除:删除节点constparser=require('@babel/parser')consttraverse=require('@babel/traverse').defaultconstgenerator=require('@babel/generator').defaultletcode=`console.log('jake')letsum=1+2letminus=2-1console.log("tom")`letast=parser.parse(code)console.log(ast)//遍历语法树traverse(ast,{标识符(路径){if(path.node.name=='sum'){path.parentPath.remove()}}})console.log(generator(ast))删除和后
