├── .gitignore
├── bin
├── webpack.js
└── webpack-graph.js
├── package.json
├── lib
├── webpack-graph.js
├── interactive.js
├── Node.js
└── Graph.js
├── README.md
└── example
└── webpackBrowsertest.svg
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /js
--------------------------------------------------------------------------------
/bin/webpack.js:
--------------------------------------------------------------------------------
1 | require("webpack/bin/webpack");
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-graph",
3 | "version": "0.1.4",
4 | "author": "Tobias Koppers @sokra",
5 | "description": "Converts JSON stats from webpack to a nice SVG-Image.",
6 | "dependencies": {
7 | "optimist": "0.2.x",
8 | "webpack": ">=0.7.2"
9 | },
10 | "licenses": [
11 | {
12 | "type": "MIT",
13 | "url": "http://www.opensource.org/licenses/mit-license.php"
14 | }
15 | ],
16 | "devDependencies": {
17 | "mocha": "*",
18 | "should": "*"
19 | },
20 | "engines": {
21 | "node": ">=0.1.30"
22 | },
23 | "homepage": "http://github.com/webpack/graph",
24 | "main": "lib/webpack-graph.js",
25 | "bin": "./bin/webpack-graph.js",
26 | "scripts": {
27 | "postinstall": "node bin/webpack lib/interactive.js js/interactive.js --colors --min --libary wpg",
28 | "test": "node node_modules/mocha/bin/_mocha --reporter spec"
29 | },
30 | "license": "MIT"
31 | }
--------------------------------------------------------------------------------
/lib/webpack-graph.js:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License http://www.opensource.org/licenses/mit-license.php
3 | Author Tobias Koppers @sokra
4 | */
5 |
6 | var Graph = require("./Graph");
7 | var interactiveSource = require("fs").readFileSync(require("path").join(__dirname, "..", "js", "interactive.js"), "utf-8");
8 |
9 | module.exports = function webpackGraph(stats, options) {
10 | options = options || {};
11 | var svg = [];
12 |
13 | var MAX_STEPS = options.maxSteps || (options.interactive ? 0 : 5000);
14 |
15 | var graph = new Graph(options, stats);
16 |
17 | var movement, i = 0;
18 | if(MAX_STEPS > 0)
19 | do {
20 | i++;
21 | movement = graph.simulateStep();
22 | var progress = Math.max(0, 1 - movement / 1000);
23 | progress = Math.floor(progress * progress * 100);
24 | var progress2 = Math.floor(i * 100 / MAX_STEPS);
25 | process.stderr.write("\b \b\b\b\b" + Math.max(progress, progress2) + "%");
26 | } while((i < 10 || movement > 10) && i < MAX_STEPS);
27 |
28 | graph.normalizePositions();
29 |
30 | graph.writeSVG(svg);
31 |
32 | if(options.interactive) {
33 | var end = svg.pop();
34 | svg.push('');
38 | svg.push(end);
39 | }
40 |
41 | if(!options.outputStream) return svg.join("");
42 | }
43 |
44 | function xmlEscape(str) {
45 | return str
46 | .replace(/&/g, "&")
47 | .replace(//g, ">");
49 | }
--------------------------------------------------------------------------------
/lib/interactive.js:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License http://www.opensource.org/licenses/mit-license.php
3 | Author Tobias Koppers @sokra
4 | */
5 | var Graph = require("./Graph");
6 |
7 | exports.use = function(json) {
8 | var graph = new Graph({
9 | width: window.innerWidth,
10 | height: window.innerHeight
11 | }).load(json);
12 |
13 | exports.paused = false;
14 | exports.STEPS_PER_TICK = 1;
15 |
16 | graph.normalizePositions();
17 | graph.applyTo(document);
18 |
19 | var draggingNode = null;
20 | var draggingPos = null;
21 |
22 | graph.modulesList.forEach(function(node, idx) {
23 | var el = document.getElementById("module"+idx);
24 | el.addEventListener("mousedown", mouseDownHandler.bind(null, node));
25 | });
26 | document.addEventListener("mousemove", mouseMoveHandler);
27 | document.addEventListener("mouseup", mouseUpHandler);
28 |
29 | function mouseDownHandler(node, event) {
30 | draggingNode = node;
31 | mouseMoveHandler(event);
32 | }
33 | function mouseMoveHandler(event) {
34 | if(!draggingNode) return;
35 | var x = event.clientX, y = event.clientY;
36 | x -= graph.MODULE_MAX_R;
37 | y -= graph.MODULE_MAX_R;
38 | x /= graph.scale;
39 | y /= graph.scale;
40 | draggingPos = [x, y];
41 | draggingNode.pos[0] = draggingPos[0];
42 | draggingNode.pos[1] = draggingPos[1];
43 | }
44 | function mouseUpHandler() {
45 | draggingNode = null;
46 | }
47 |
48 | setTimeout(function tick() {
49 | if(!exports.paused) {
50 | for(var i = 0; i < exports.STEPS_PER_TICK; i++) {
51 | graph.simulateStep();
52 | if(draggingNode) {
53 | draggingNode.pos[0] = draggingPos[0];
54 | draggingNode.pos[1] = draggingPos[1];
55 | }
56 | }
57 | } else if(exports.single) {
58 | exports.single = false;
59 | graph.simulateStep();
60 | }
61 | if(!draggingNode)
62 | graph.normalizePositions();
63 | graph.applyTo(document);
64 | setTimeout(tick, 1);
65 | }, 100);
66 | return graph;
67 | }
68 |
69 | exports.Graph = Graph;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # webpack-graph
2 |
3 | It visualize your dependency tree as svg image.
4 |
5 | Provide it with webpack stats (as JSON) for version > 0.7.
6 |
7 | You can generate them by calling webpack with `--json`.
8 |
9 | ## Command Line
10 |
11 | `webpack-graph [ []]`
12 |
13 | If you don't provide the files as parameters `webpack-graph` will read them from `stdin` or write it to `stdout`.
14 |
15 | `--context ` - Shorten filenames according to this context
16 |
17 | `--width ` - The max width of the output svg
18 |
19 | `--height ` - The max height of the output svg
20 |
21 | `--steps ` - Limit the simulation steps
22 |
23 | `--interactive` - Emit simulation code to browser
24 |
25 | `--color-by-loaders` - Choose colors by loaders
26 |
27 | `--color-by-module` - Choose colors by loaders
28 |
29 | `--color-switch` - Chosse colors by hovering
30 |
31 | ## Resulting Image
32 |
33 | * Circles are modules/contexts
34 | * The size visualize the file size.
35 | * The color visualize the chunks in which the module is emitted.
36 | * Connections are dependencies
37 | * webpack-graph try to guess libaries and connect them with thin lines
38 | * Dashed lines visualize async requires.
39 | * Hover modules/contexts to display more info
40 | * Tooltip display module name and loaders
41 | * Tooltip display chunks
42 | * Green lines display requires *from* other modules/contexts
43 | * Red lines display requires *to* other modules/contexts
44 | * Brown lines display requires *to* and *from* other modules/contexts
45 | * In interactive mode
46 | * You can drag modules/contexts with your mouse
47 | * Layouting happens live
48 | * Only tested on latest Chrome and Firefox
49 | * Older browsers are not supported
50 |
51 | ### Example
52 |
53 | 
54 |
55 | [Interactive version](http://webpack.github.com/graph/example/webpackBrowsertestInteractive.svg)
56 |
57 | See more examples in webpack examples
--------------------------------------------------------------------------------
/bin/webpack-graph.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /*
4 | MIT License http://www.opensource.org/licenses/mit-license.php
5 | Author Tobias Koppers @sokra
6 | */
7 | var path = require("path");
8 | var fs = require("fs");
9 | var util = require("util");
10 |
11 | var argv = require("optimist")
12 | .usage("webpack-graph " + require("../package.json").version + "\n" +
13 | "Usage: $0 [ [