ast叫做抽象语法树, 如babel, eslint, typescript和webpack都是借助了抽象语法树,做语法解析(语法分词和语法分析)。
分析和语法分析在线
https://astexplorer.net/
安装
需要操作 AST
代码,这里,我们需要借助两个库,分别是 @babel/core
和 babel-types
。
其中 @babel/core
是 babel
的核心库,用来实现核心转换引擎,babel-types
类型判断,用于生成AST
零部件
//babel 核心库,用来实现核心转换引擎 const babel = require('@babel/core') //类型判断,生成AST零部件 const types = require('babel-types') //源代码 const code = `const sum=(a,b)=>a+b;` let result = babel.transform(code,{ plugins:[ { visitor } ] })
书写plugin
1. arrowFunction
1 let visitor = { 2 ArrowFunctionExpression(path){ 3 let params = path.node.params; 4 //创建一个blockStatement 5 let blockStatement = types.blockStatement([ 6 types.returnStatement(types.binaryExpression( 7 '+', 8 types.identifier('a'), 9 types.identifier('b') 10 )) 11 ]); 12 //创建一个函数 13 let func = types.functionExpression(null, params, blockStatement, false, false); 14 //替换 15 path.replaceWith(func); 16 } 17 };
2.classFunction
1 const babel = require("@babel/core"); 2 const { functionExpression } = require("babel-types"); 3 //类型判断,生成AST零部件 4 const types = require("babel-types"); 5 6 //源代码 7 const code = `class Person { 8 constructor(name) { 9 this.name=name; 10 } 11 sayName() { 12 return this.name; 13 } 14 }`; 15 const expect = `function Person(name) { 16 this.name = name; 17 } 18 Person.prototype.sayName = function () { 19 return this.name; 20 };`; 21 let visitor = { 22 ClassDeclaration(path) { 23 const {id, body} = path.node; 24 const bbody = body.body[0]; 25 let funs = []; 26 const constructor = types.functionDeclaration(id, bbody.params, bbody.body, false, false); 27 funs.push(constructor); 28 const pbody = body.body[1]; 29 30 const source = types.memberExpression(id, types.identifier('prototype'), false); 31 const left = types.memberExpression(source,pbody.key,pbody.computed); 32 const right = types.functionExpression(null, pbody.params, pbody.body, false, false ); 33 const proto = types.assignmentExpression('=', left, right); 34 funs.push(proto); 35 path.replaceWithMultiple(funs); 36 }, 37 }; 38 let result = babel.transform(code, { 39 plugins: [ 40 { 41 visitor, 42 }, 43 ], 44 }); 45 console.log(result.code);