AST基础知识|babel库中path常用方法总结
关注它,不迷路。
本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
1. path源码学习:
path相关的源代码在这个js文件中,大家可以直接照着源码学习:
\node_modules\@babel\traverse\lib\path 当然,第一个需要学习的文件应该是这个:
node_modules\@babel\traverse\lib\path\index.js 在本文中,选出部分常用的方法大家参考,更多的知识请自行学习源码。
2. path常用方法介绍
path.toString
用来获取当前遍历path的js源代码,调用方式:
let sourceCode = path.toString(); 这个非常有用,经常用于定于插件遍历的path,以便分析问题。如果想通过 path.node来获取源代码,可以使用 generator 函数来获取:
let sourceCode = generator(path.node).code; path.replaceWith
(单)节点替换函数,调用方式:
path.replaceWith(newNode); 实参一般是 node 类型,即将当前遍历的path替换为 实参里的 新节点。
注意,它不能用于 Array 的替换,即实参不能是Array类型。
path.replaceWithMultiple
(多)节点替换函数,调用方式:
path.rreplaceWithMultiple(ArrayNode); 实参一般是 Array 类型,它只能用于 Array 的替换。即所有需要替换的节点在一个Array里面,常见的替换如 Block 类型节点里的 body.body。
path.remove
节点的删除,调用方式:
path.remove(); 直接调用即可将当前遍历的所有符合条件的路径全部删除,所以使用的时候需要注意。
path.insertBefore
在当前节点前面插入新的节点。调用方式:
path.insertBefore(newNode); path.insertAfter
在当前节点后面插入新的节点。调用方式:
path.insertAfter(newNode); path.traverse
在当前节点下遍历其他的节点,比如有如下for循环:
for(;;)
{a = b;b = c;c =d;
} 想要遍历这个for循环下面的 赋值语句,可以借助该函数进行遍历:
const visitFor =
{ForStatement(path){......path.traverse({AssignmentExpression(_path){......},}),......},
} path.get
获取当前路径下的子孙节点。调用方式:
let newPath = path.get(key) 形参key是一个字符串,以 . 隔开。 其源代码:
function get(key, context) {if (context === true) context = this.context;const parts = key.split(".");if (parts.length === 1) {return this._getKey(key, context);} else {return this._getPattern(parts, context);}} 假如当前的代码如下:
var a = 1; 你遍历了 VariableDeclaration 类型,想要获取 右边的这个 1,可以写如下代码:
const visitVar =
{VariableDeclaration(path){let initPath = path.get('declarations.0.init');......},
} path.getSibling
根据key值来获取节点,这个方法我很少用,大家可以试试。
path.getPrevSibling
获取当前path的前一个兄弟节点,返回的是path类型。
path.getAllPrevSiblings
获取当前path的所有前兄弟节点,返回的是Array类型,其元素都是path类型。
path.getNextSibling
获取当前path的后一个兄弟节点,返回的是path类型。
path.getAllNextSiblings
获取当前path的所有后兄弟节点,返回的是Array类型,其元素都是path类型。
path.evaluate
用于计算表达式的值,大家可以参考 constantFold 插件的写法。
https://wx.zsxq.com/dweb2/index/topic_detail/185515841482512 path.findParent
向上查找满足回调函数特征的path,即判断上级路径是否包含有XXX类型的节点:
function findParent(callback) {let path = this;while (path = path.parentPath) {if (callback(path)) return path;}return null;} 很简单,先从父级节点开始进行遍历,然后一直循环,直到满足回调函数的条件为止。如果找不到则返回null。回调函数怎么写,可以参考下面的代码:
function getFunctionParent() {return this.findParent(p => p.isFunction());} path.find
功能与 path.findParent 方法一样,只不过从当前path开始进行遍历。
path.getFunctionParent
获取函数类型父节点,如果不存在,返回 null。
path.getStatementParent
获取Statement类型父节点,这个基本上都会有返回值,如果当前遍历的是 Program 或者 File 节点,则会报错。
path.getAncestry
获取所有的祖先节点,没有实参,返回的是一个Array对象。源码也很简单:
function getAncestry() {let path = this;const paths = [];do {paths.push(path);} while (path = path.parentPath);return paths;} path.isAncestor
判断当前遍历的节点是否为实参的祖先节点,调用方式:
path.isAncestor(maybeDescendant) 实参传入 path 类型即可。
path.isDescendant
判断当前遍历的节点是否为实参的子孙节点,调用方式:
path.isDescendant(maybeAncestor) 实参传入 path 类型即可。
今天的文章就分享到这里,后续分享更多的技巧,敬请期待。

欢迎加入知识星球,学习更多AST和爬虫技巧。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
