babel-traverse是一个对ast进行遍历的工具。相似于字符串的replace方法,指定一个正则表达式,就能对字符串进行替换。只不过babel-traverse是对ast进行替换。
使用ast对代码修改会更有优点,支持各类语法匹配模式,好比条件表达式、函数表达式,while循环等。前提是代码是符合js、ts语法的。
官方文档地址 https://babeljs.io/docs/en/ne...
首先经过babel-parse将字符串转化为ast,就能够对ast进行遍历了,好比想要寻找全部的function就能够这么写。node
const parser = require('@babel/parser') const t = require('@babel/types') const traverse = require('@babel/traverse').default let code = 'function a() {}' const ast = parser.parse(code) traverse(ast, { FunctionDeclaration(path) { const node = path.node // 获取函数名称等 path.replaceWith()//替换为新的节点 path.remove() // 删除当前节点 path.skip() 跳过子节点 let copyNode = t.cloneNode(node)//复制当前节点 traverse(copyNode, {}, {}, path)// 对子树进行遍历和替换,不影响当前的path } })
接下来若是想要对某些函数进行替换,就须要使用path这个参数,比较经常使用的是replaceWith方法,能够将当前节点替换为新的节点。也能够拿到node变量,直接修改,具体使用哪一种形式,还要看须要替换为何内容。
#path.skip()
由于ast是一颗树,若是须要跳过对子树的遍历,就能够使用skip方法,常见的状况是已经找到了对应的节点,就没有必要再遍历子树了。
#path.replaceWith()
不得不提的是@babel/types
这个包,replaceWith的参数就能够经过babel/types来获取,好比须要将function修改成一个遍历申明,能够这样写正则表达式
let newNode = t.variableDeclaration( 'let', [t.variableDeclarator(t.identifier('a'), t.stringLiteral('123'))] ) path.replaceWith(newNode)
这样function a就变成了 let a = '123'
最后能够经过@babel/generator将ast输出为字符串,就能够看到修改的效果了。babel
const output = generate(ast, {}, code)