parse & generator 组件
parse
作用是 代码 转化为 AST 结构
const parser = require("@babel/parser"); // 需要导入 let ast = parser.parse(js_code) // 代码转化为 ast 结构,与网站上一样 let ast1 = parser.parse(js_code,{ sourceType:"module", // 如果有 import export 关键字,需要使用该参数 }) console.log(JSON.stringify(ast, null, 2))
generator
作用是 AST结构 转化为 代码
let code = generator(ast).code let code1 = generator(ast, { retainLines: false, // 默认 false ,是否输出与源代码相同的行号 comments: false, // 默认 true,是否保留注释 compact: true // 默认 false,是否压缩代码 }).code
traverse & visitor 组件
traverse
用来遍历
AST结构 的节点,简单点说就是把所有节点
都运行一遍
traverse
使用的深度优先
策略
// 导入 const traverse = require("@babel/traverse").default; // 遍历节点 const generator = require("@babel/generator").default // AST 转换为 代码 // 相关操作 let visitor = {} visitor.FunctionExpression = function (path) { console.log("mmmmm") } traverse(ast,visitor) /* 源码有两个 函数节点 所以输出两次 mmmm mmmm */
visitor 三种写法
按照自己的 喜好 选择,最常用的 visitor2
let visitor1 = { FunctionExpression: function (path){ console.log('...') } } let visitor2 = { FunctionExpression(path){ console.log('...') } } let visitor3 = { FunctionExpression: { enter(path){ console.log('进入 -> 函数节点') }, exit(path){ console.log('退出 <- 函数节点') } } } traverse(ast,visitor3)
visitor 组合写法
使用
|
组合不同的类型
let visitor1 = { 'FunctionExpression|BinaryExpression': function (path){ console.log('...') } } let visitor2 = { 'FunctionExpression|BinaryExpression'(path){ console.log('...') } } let visitor3 = { 'FunctionExpression|BinaryExpression': { enter(path){ console.log('进入 -> 节点') }, exit(path){ console.log('退出 <- 节点') } } } traverse(ast,visitor3)
使用
多个函数
处理 节点,会按照函数顺序 执行
function fun1(path) { console.log('11') } function fun2(path) { console.log('22') } let visitor = { FunctionExpression: { enter: [fun1, fun2] } } traverse(ast,visitor)
traverse 并非必须从头遍历
// 修改函数 第一个参数为 x ,并修改函数内 所有用了 该参数的地方 const updateParamNameVisitor = { Identifier(path) { if (path.node.name === this.paramName) { path.node.name = "x" } } } const visitor = { FunctionExpression(path) { // 遍历函数节点 const paramName = path.node.params[0].name // 内部循环 path.traverse(updateParamNameVisitor, { paramName // 向 子循环 传递参数 }) } } traverse(ast, visitor)
版权声明:《 【AST 基础】一、AST 的 parse & generator & traverse & visitor 组件 》为明妃原创文章,转载请注明出处!
最后编辑:2022-4-9 09:04:03