8

babel-traverse是一个对ast进行遍历的工具。类似于字符串的replace方法,指定一个正则表达式,就能对字符串进行替换。只不过babel-traverse是对ast进行替换。
使用ast对代码修改会更有优势,支持各种语法匹配模式,比如条件表达式、函数表达式,while循环等。前提是代码是符合js、ts语法的。
官方文档地址 https://babeljs.io/docs/en/ne...
首先通过babel-parse将字符串转化为ast,就可以对ast进行遍历了,比如想要寻找所有的function就可以这么写。

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输出为字符串,就可以看到修改的效果了。

const output = generate(ast, {}, code)

江雨
445 声望2 粉丝

引用和评论

0 条评论