npm ls with two modifications:
- only explicitly required dependencies
- finds cyclical requires
Dependencies are analyzed using parts of the browserify toolchain.
Install globally and give it a path to a local package or a file:
$ npm install -g npm-graph
$ npm-graph node_modules/irc-stream/irc-stream└───irc
If all modules in "dependencies" are used, then this should look like
$ npm-graph node_modules/irc-stream/ -birc-stream├──┬irc│ ├───net│ ├───tls│ └───util└───stream
This can give some at a glance information about how browserifiable the module is.
File by file inclusion:
$ npm-graph node_modules/irc-stream/ -lirc-stream└──┬irc├───./codes└───./colors
Cycles are detected and shown in the tree with a
↪ after an offender. As an example, readable-stream (tsk tsk) closes a cyclical loop by having Duplex depend on Writable and vice versa (albeit lightly).
$ npm install email@example.com$ npm-graph node_modules/readable-stream/writable.js -lwritable.js└─┬./lib/_stream_writable.js├─┬./_stream_duplex ↪ ./_stream_writable│ ├─┬./_stream_readable│ │ ├──core-util-is│ │ ├──inherits│ │ ├──isarray│ │ └──string_decoder/│ ├──core-util-is│ └──inherits├──core-util-is└──inherits
The mutual file inclusions would normally cause a recursion overflow when generating the tree if we hadn't first found the strongly connected components in the inclusion digraph and manually broken the cycle.
( •_•)( •_•)>⌐■-■(⌐■_■)
The cyclical components from Tarjan's algorithm are also available with
$ npm-graph node_modules/readable-stream/writable.js -l -c[ [ './node_modules/readable-stream/lib/_stream_writable.js','./node_modules/readable-stream/lib/_stream_duplex.js' ] ]
In this case, a 2-cycle.
MIT-Licensed. See LICENSE file for details.