Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I finally managed this using <a href="https://github.com/mishoo/UglifyJS2" rel="nofollow noreferrer">UglifyJS2</a> and <a href="http://graphviz.org/Documentation.php" rel="nofollow noreferrer">Dot/GraphViz</a>, in a sort of combination of the above answer and the answers to the linked question.</p> <p>The missing part, for me, was how to filter the parsed AST. It turns out that UglifyJS has the TreeWalker object, which basically applys a function to each node of the AST. This is the code I have so far:</p> <pre><code>//to be run using nodejs var UglifyJS = require('uglify-js') var fs = require('fs'); var util = require('util'); var file = 'path/to/file...'; //read in the code var code = fs.readFileSync(file, "utf8"); //parse it to AST var toplevel = UglifyJS.parse(code); //open the output DOT file var out = fs.openSync('path/to/output/file...', 'w'); //output the start of a directed graph in DOT notation fs.writeSync(out, 'digraph test{\n'); //use a tree walker to examine each node var walker = new UglifyJS.TreeWalker(function(node){ //check for function calls if (node instanceof UglifyJS.AST_Call) { if(node.expression.name !== undefined) { //find where the calling function is defined var p = walker.find_parent(UglifyJS.AST_Defun); if(p !== undefined) { //filter out unneccessary stuff, eg calls to external libraries or constructors if(node.expression.name == "$" || node.expression.name == "Number" || node.expression.name =="Date") { //NOTE: $ is from jquery, and causes problems if it's in the DOT file. //It's also very frequent, so even replacing it with a safe string //results in a very cluttered graph } else { fs.writeSync(out, p.name.name); fs.writeSync(out, " -&gt; "); fs.writeSync(out, node.expression.name); fs.writeSync(out, "\n"); } } else { //it's a top level function fs.writeSync(out, node.expression.name); fs.writeSync(out, "\n"); } } } if(node instanceof UglifyJS.AST_Defun) { //defined but not called fs.writeSync(out, node.name.name); fs.writeSync(out, "\n"); } }); //analyse the AST toplevel.walk(walker); //finally, write out the closing bracket fs.writeSync(out, '}'); </code></pre> <p>I run it with <a href="http://nodejs.org/" rel="nofollow noreferrer">node</a>, and then put the output through</p> <p><code>dot -Tpng -o graph_name.png dot_file_name.dot</code></p> <p>Notes:</p> <p>It gives a pretty basic graph - only black and white and no formatting. </p> <p>It doesn't catch ajax at all, and presumably not stuff like <code>eval</code> or <code>with</code> either, as <a href="https://stackoverflow.com/a/9746719/1856824">others have mentioned</a>. </p> <p>Also, as it stands it includes in the graph: functions called by other functions (and consequently functions that call other functions), functions that are called independantly, AND functions that are defined but not called.</p> <p>As a result of all this, it may miss things that are relevant, or include things that are not. It's a start though, and appears to accomplish what I was after, and what led me to this question in the first place.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload