我最终使用 UglifyJS2 和 Dot/GraphViz 成功了,这是上面答案和相关问题的答案的一种组合。
对我来说缺失的部分是如何过滤解析出的 AST。事实证明,UglifyJS 有 TreeWalker 对象,它基本上将一个函数应用于 AST 的每个节点。目前我的代码如下:
var UglifyJS = require('uglify-js')
var fs = require('fs');
var util = require('util');
var file = 'path/to/file...';
var code = fs.readFileSync(file, "utf8");
var toplevel = UglifyJS.parse(code);
var out = fs.openSync('path/to/output/file...', 'w');
fs.writeSync(out, 'digraph test{\n');
var walker = new UglifyJS.TreeWalker(function(node){
if (node instanceof UglifyJS.AST_Call) {
if(node.expression.name !== undefined)
{
var p = walker.find_parent(UglifyJS.AST_Defun);
if(p !== undefined)
{
if(node.expression.name == "$" || node.expression.name == "Number" || node.expression.name =="Date")
{
}
else
{
fs.writeSync(out, p.name.name);
fs.writeSync(out, " -> ");
fs.writeSync(out, node.expression.name);
fs.writeSync(out, "\n");
}
}
else
{
fs.writeSync(out, node.expression.name);
fs.writeSync(out, "\n");
}
}
}
if(node instanceof UglifyJS.AST_Defun)
{
fs.writeSync(out, node.name.name);
fs.writeSync(out, "\n");
}
});
toplevel.walk(walker);
fs.writeSync(out, '}');
我用
node运行它,然后通过
dot -Tpng -o graph_name.png dot_file_name.dot
输出。
注意:
它只提供了一个非常基本的图表——只有黑白两色,没有任何格式。
它无法捕获ajax,而且可能也无法捕获像
eval
或
with
这样的内容,正如
其他人所提到的的那样。
此外,它的图表包括:被其他函数调用的函数(因此调用其他函数的函数),独立调用的函数和被定义但未被调用的函数。
由于所有这些原因,它可能会错过一些相关的内容,或者包含一些不相关的内容。不过,它是一个起点,并似乎达到了我最初追求的目标,也正是因为这个目标,我才来到这个问题。