babel-traverse之常用api

江雨 2020-05-26 18:45:10
原文地址:https://segmentfault.com/a/1190000022345699

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)

声明:该文章系转载,转载该文章的目的在于更广泛的传递信息,并不代表本网站赞同其观点,文章内容仅供参考。

本站是一个个人学习和交流平台,网站上部分文章为网站管理员和网友从相关媒体转载而来,并不用于任何商业目的,内容为作者个人观点, 并不代表本网站赞同其观点和对其真实性负责。

我们已经尽可能的对作者和来源进行了通告,但是可能由于能力有限或疏忽,导致作者和来源有误,亦可能您并不期望您的作品在我们的网站上发布。我们为这些问题向您致歉,如果您在我站上发现此类问题,请及时联系我们,我们将根据您的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。