diff --git a/README.md b/README.md index 7d607ff..a9b2742 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ var list = dependencyTree.toList({ * `nonExistent`: array used for storing the list of partial paths that do not exist * `filter`: a function used to determine if a module (and its subtree) should be included in the dependency tree - The first argument given to the filter is an absolute filepath to the dependency and the second is the filepath to the currently traversed file. Should return a `Boolean`. If it returns `true`, the module is included in the resulting tree. +* `verbose`: wether to return the tree as a nested list with additional data for each dependency * `detective`: object with configuration specific to detectives used to find dependencies of a file - for example `detective.amd.skipLazyLoaded: true` tells the AMD detective to omit inner requires - See [precinct's usage docs](https://github.com/dependents/node-precinct#usage) for the list of module types you can pass options to. @@ -77,6 +78,40 @@ Example: This structure was chosen to serve as a visual representation of the dependency tree for use in the [Dependents](https://github.com/mrjoelkemp/sublime-dependents) plugin. +Example using `verbose: true`: + +```js +[{ + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/a.js', + partial: './test/example/extended/a.js', + dependencies: [{ + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/b.js', + partial: './test/example/extended/b.js', + dependencies: [{ + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/d.js', + partial: 'test/example/extended/d.js', + dependencies: [] + }, { + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/e.js', + partial: 'test/example/extended/e.js', + dependencies: [] + }] + }, { + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/c.js', + partial: './test/example/extended/c.js', + dependencies: [{ + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/f.js', + partial: 'test/example/extended/f.js', + dependencies: [] + }, { + resolved: '/Users/mrjoelkemp/Documents/node-dependency-tree/test/example/extended/g.js', + partial: 'test/example/extended/g.js', + dependencies: [] + }] + } +}] +``` + ##### CLI version * Assumes a global install: `npm install -g dependency-tree` diff --git a/index.js b/index.js index a1c1701..a9ec777 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,7 @@ const Config = require('./lib/Config'); * Format is a filename -> tree as list lookup table * @param {Array} [options.nonExistent] - List of partials that do not exist * @param {Boolean} [options.isListForm=false] + * @param {Boolean} [options.verbose=false] Return a verbose tree in list form * @param {String|Object} [options.tsConfig] Path to a typescript config (or a preloaded one). * @return {Object} */ @@ -29,7 +30,7 @@ module.exports = function(options) { if (!fs.existsSync(config.filename)) { debug('file ' + config.filename + ' does not exist'); - return config.isListForm ? [] : {}; + return config.isListForm || config.verbose ? [] : {}; } const results = traverse(config); @@ -43,6 +44,14 @@ module.exports = function(options) { debug('list form of results requested'); tree = Array.from(results); + } else if (config.verbose) { + debug('verbose form of results requested'); + + tree = [{ + resolved: config.filename, + partial: null, + dependencies: results, + }]; } else { debug('object form of results requested'); @@ -126,7 +135,11 @@ module.exports._getDependencies = function(config) { continue; } - resolvedDependencies.push(result); + if (config.verbose) { + resolvedDependencies.push({resolved: result, partial: dep}); + } else { + resolvedDependencies.push(result); + } } return resolvedDependencies; @@ -137,7 +150,14 @@ module.exports._getDependencies = function(config) { * @return {Object|Set} */ function traverse(config) { - let subTree = config.isListForm ? new Set() : {}; + let subTree; + if (config.isListForm) { + subTree = new Set(); + } else if (config.verbose) { + subTree = []; + } else { + subTree = {}; + } debug('traversing ' + config.filename); @@ -151,7 +171,7 @@ function traverse(config) { debug('cabinet-resolved all dependencies: ', dependencies); // Prevents cycles by eagerly marking the current file as read // so that any dependent dependencies exit - config.visited[config.filename] = config.isListForm ? [] : {}; + config.visited[config.filename] = config.isListForm || config.verbose ? [] : {}; if (config.filter) { debug('using filter function to filter out dependencies'); @@ -164,21 +184,27 @@ function traverse(config) { for (let i = 0, l = dependencies.length; i < l; i++) { const d = dependencies[i]; + const resolved = config.verbose ? d.resolved : d; const localConfig = config.clone(); - localConfig.filename = d; + localConfig.filename = resolved; if (localConfig.isListForm) { for (let item of traverse(localConfig)) { subTree.add(item); } + } else if (localConfig.verbose) { + d.dependencies = traverse(localConfig); + subTree.push(d); } else { - subTree[d] = traverse(localConfig); + subTree[resolved] = traverse(localConfig); } } if (config.isListForm) { subTree.add(config.filename); config.visited[config.filename].push(...subTree); + } else if (config.verbose) { + config.visited[config.filename] = subTree; } else { config.visited[config.filename] = subTree; } diff --git a/lib/Config.js b/lib/Config.js index 336f3ac..c965c73 100644 --- a/lib/Config.js +++ b/lib/Config.js @@ -9,6 +9,7 @@ class Config { this.directory = options.directory || options.root; this.visited = options.visited || {}; this.nonExistent = options.nonExistent || []; + this.verbose = options.verbose; this.isListForm = options.isListForm; this.requireConfig = options.config || options.requireConfig; this.webpackConfig = options.webpackConfig;