Javascript-Babel-AST-traverse-NodePath.evaluate方法增强
本文最后更新于:2020年12月30日 上午
信息
NodePath.evaluate()
方法非常的好用,但本身也存在着一些限制
进行一些源码修改能提升它的能力
处理更多全局函数
NodePath.evaluate()
方法不支持对parseInt
等全局函数的处理
我们可以通过修改源码,让其支持
- 打开方法定义文件,查看函数处理定义
文件路径:node_modules\@babel\traverse\lib\path\evaluation.js
- 在文件中找到会处理的全局函数定义
在代码中找到定义位置定义包含两种:1
2const VALID_CALLEES = ["String", "Number", "Math"];
const INVALID_METHODS = ["random"];
VALID_CALLEES
会进行处理的全局函数INVALID_METHODS
只要包含就不会处理的全局函数根据你的需要对定义进行修改即可
例:希望支持处理
parseInt
函数
在会进行处理的定义里添加函数名即可
1 |
|
"string"["length"]
引用不支持
我们知道访问object对象有两种方法,"string"["length"]
和 "string".length
但 NodePath.evaluate()
只会处理 "string".length
这种方式的表达式,而 "string"["length"]
是不会直接进行处理的
你可以通过可以把 "string"["length"]
转变为 "string".length
这种形式的方式来实现适配
也可以通过修改源码达到目的
打开方法定义文件,查看函数处理定义
文件路径:node_modules\@babel\traverse\lib\path\evaluation.js
找到
_evaluate
函数,查看 对MemberExpression
表达式的处理1
2
3
4
5
6
7
8
9
10
11
12
13if (path.isMemberExpression() && !path.parentPath.isCallExpression({
callee: node
})) {
const property = path.get("property");
const object = path.get("object");
if (object.isLiteral() && property.isIdentifier()) {
const value = object.node.value;
const type = typeof value;
if (type === "number" || type === "string") {
return value[property.node.name];
}
}
}它主要处理在第二个 if 语句里面
1
if (object.isLiteral() && property.isIdentifier()) {......}
但是它只考虑了
object
是字面量且property
必须是Idernifier
的情况,也就是类似"string".length
的表达式
现在把另外一种情况的代码补充进去, 代码如下:
1 |
|
将代码直接添加到 if
语句的后面即可
多了一种判断逻辑和对应的处理逻辑,就能处理"string"["length"]
类型的代码了
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!