Skip to content
This repository was archived by the owner on Apr 12, 2018. It is now read-only.

Commit f80d429

Browse files
committedMar 5, 2015
Initial commit
0 parents  commit f80d429

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed
 

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
node_modules/

‎README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# webpack-dependency-tree
2+
3+
Builds a dependency tree from webpack stats
4+
5+
### fromStats(stats, [opts])
6+
7+
Builds a dependency tree from webpack stats.
8+
9+
`opts` can be:
10+
11+
* `opts.packageDescriptors`: List of package descriptor files to look for in package directories. Defaults to `['package.json', 'bower.json', 'component.json']`
12+
13+
### treeToString(tree, [opts])
14+
15+
Converts a dependency tree to an ASCII hierarchy representation.
16+
17+
`opts` can be:
18+
19+
* `opts.pretty`: Add colors and styles to the output
20+
* `opts.fullPaths`: Display full paths instead of relative paths.

‎index.js

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
var path = require('path');
2+
3+
var archy = require('archy');
4+
var chalk = require('chalk');
5+
var resolve = require('enhanced-resolve');
6+
7+
exports.fromStats = function buildTree(stats, opts) {
8+
opts = opts || {};
9+
opts.packageDescriptors = opts.packageDescriptors || ['package.json', 'bower.json', 'component.json'];
10+
11+
// Build a module dependency tree
12+
var tree = {};
13+
stats.modules.forEach(function(mod) {
14+
// Ignore origin modules
15+
if (mod.name.indexOf('~') === -1) {
16+
return;
17+
}
18+
19+
// Resolve webpack query string and loaders to retrieve the resource path.
20+
// webpack dependencies are prepended with (webpack)
21+
// Module directories are represented by a ~
22+
var modulePath = resolve.parse(mod.name).resource.path.replace('(webpack)', './~/webpack');
23+
var moduleFullPath = resolve.parse(mod.identifier).resource.path;
24+
25+
// The following code maps every `~/module_name` in `modulePath` to its corresponding
26+
// `module_folder/module_name` in `moduleFullPath`
27+
28+
// Split at each `~/module_name` and escape for use in a regexp
29+
var splitParts = modulePath.split(/~\/[^\/]+\//).map(escapeRegExp);
30+
31+
// Find and traverse every `module_folder/module_name` construct in `moduleFullPath`
32+
var parentTree = tree;
33+
for (var i = 1; i < splitParts.length; i++) {
34+
// Remove everything before the module occurrence so that match.index points
35+
// to the beginning of the module_folder/module_name construct
36+
var regexpParts = splitParts.slice(i);
37+
var regexpHead = '([^\/]+\/([^\/]+)\/)'; // match `module_folder/module_name`
38+
var regexpTail = regexpParts.join('[^\/]+\/[^\/]+\/'); // match the rest of the path
39+
var regexp = new RegExp(regexpHead + regexpTail + '$');
40+
41+
var match = moduleFullPath.match(regexp);
42+
if (!match) {
43+
// Shouldn't happen
44+
return;
45+
}
46+
47+
var packagePath = moduleFullPath.slice(0, match.index + match[1].length);
48+
49+
// Retrieve the child module version from its descriptor file (package.json, bower.json, ...)
50+
var packageVersion = 'unknown';
51+
for (var j = 0; j < packageDescriptors.length; j++) {
52+
try {
53+
packageVersion = require(packagePath + packageDescriptors[j]).version;
54+
break;
55+
} catch (e) {
56+
// do nothing
57+
}
58+
}
59+
60+
var packageName = match[2];
61+
var package = parentTree[packageName];
62+
if (!package) {
63+
parentTree[packageName] = package = {
64+
name: packageName,
65+
version: packageVersion,
66+
path: packagePath,
67+
tree: {}
68+
};
69+
}
70+
parentTree = package.tree;
71+
}
72+
});
73+
74+
return tree;
75+
};
76+
77+
exports.treeToString = function treeToString(tree, opts) {
78+
opts = opts || {};
79+
opts.pretty = opts.pretty || false;
80+
opts.fullPaths = opts.fullPaths || false;
81+
82+
// Node that will eventually be passed to archy
83+
var topNode = {
84+
label: '',
85+
nodes: []
86+
};
87+
88+
// Recursively build an archy node tree from our package tree
89+
(function recursiveTreeBuild(tree, node) {
90+
for (var key in tree) {
91+
var package = tree[key];
92+
var packageName = opts.pretty ? chalk.underline(package.name) : package.name;
93+
var packagePath = opts.fullPaths ? package.path : path.relative(path.dirname(module.parent.filename), package.path);
94+
packagePath = opts.pretty ? chalk.grey(packagePath) : packagePath;
95+
96+
var childNode = {
97+
label: packageName + '@' + package.version + '\n' + packagePath,
98+
nodes: []
99+
};
100+
recursiveTreeBuild(package.tree, childNode);
101+
node.nodes.push(childNode);
102+
};
103+
})(tree, topNode);
104+
105+
return archy(topNode);
106+
};

‎package.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "webpack-dependency-tree",
3+
"version": "0.0.1",
4+
"description": "Builds a dependency tree from webpack stats",
5+
"author": "Alexandre Kirszenberg <alexandre.kirszenberg@gmail.com>",
6+
"keywords": [
7+
"webpack",
8+
"tree",
9+
"graph",
10+
"dependency",
11+
"module"
12+
],
13+
"main": "index.js",
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/botify-labs/webpack-dependency-tree.git"
17+
},
18+
"license": "MIT",
19+
"dependencies": {
20+
"archy": "^1.0.0",
21+
"chalk": "^1.0.0",
22+
"enhanced-resolve": "^0.8.4"
23+
}
24+
}

0 commit comments

Comments
 (0)
This repository has been archived.