UNPKG

13.8 kBMarkdownView Raw
1<p align="center">
2 <img alt="madge" src="http://pahen.github.io/madge/logo.svg" width="320">
3</p>
4
5<p align="center">
6 <img alt="Last version" src="https://img.shields.io/github/tag/pahen/madge.svg?style=flat-square" />
7 <a href="https://travis-ci.org/pahen/madge">
8 <img alt="Build Status" src="http://img.shields.io/travis/pahen/madge/master.svg?style=flat-square" />
9 </a>
10 <a href="https://david-dm.org/pahen/madge">
11 <img alt="Dependency status" src="http://img.shields.io/david/pahen/madge.svg?style=flat-square" />
12 </a>
13 <a href="https://david-dm.org/pahen/madge#info=devDependencies">
14 <img alg="Dev Dependencies status" src="http://img.shields.io/david/dev/pahen/madge.svg?style=flat-square" />
15 </a>
16 <a href="https://www.npmjs.org/package/madge">
17 <img alg="NPM Status" src="http://img.shields.io/npm/dm/madge.svg?style=flat-square" />
18 </a>
19 <a href="https://paypal.me/pahen" target="_blank">
20 <img alt="Donate" src="https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square" />
21 </a>
22</p>
23
24
25**Madge** is a developer tool for generating a visual graph of your module dependencies, finding circular dependencies, and give you other useful info. Joel Kemp's awesome [dependency-tree](https://github.com/mrjoelkemp/node-dependency-tree) is used for extracting the dependency tree.
26
27
28* Works for JavaScript (AMD, CommonJS, and ES6 modules)
29* Also works for CSS preprocessors (Sass, Stylus, and Less)
30* NPM installed dependencies are excluded by default (can be enabled)
31* All core Node.js modules (assert, path, fs, etc) are excluded
32* Will traverse child dependencies automatically
33
34Read the [changelog](CHANGELOG.md) for latest changes.
35
36> I've worked with Madge on my free time for the last couple of years and it's been a great experience. It started as an experiment but turned out to be a very useful tool for many developers. I have many ideas for the project and it would definitely be easier to dedicate more time to it with some [financial support](#donations) 🙏
37>
38> Regardless of your contribution, thanks for your support!
39
40## Examples
41
42> Graph generated from madge's own code and dependencies.
43
44<a href="http://pahen.github.io/madge/madge.svg">
45 <img src="http://pahen.github.io/madge/madge.svg" width="888"/>
46</a>
47
48> A graph with circular dependencies. Blue has dependencies, green has no dependencies, and red has circular dependencies.
49
50<a href="http://pahen.github.io/madge/simple.svg">
51 <img src="http://pahen.github.io/madge/simple.svg" width="300"/>
52</a>
53
54## See it in action
55
56<a href="https://asciinema.org/a/l9tM7lIraCpmzH0rdWw2KLrMc?autoplay=1">
57 <img src="https://asciinema.org/a/l9tM7lIraCpmzH0rdWw2KLrMc.png" width="590"/>
58</a>
59
60# Installation
61
62```sh
63npm -g install madge
64```
65
66## Graphviz (optional)
67
68> [Graphviz](http://www.graphviz.org/) is only required if you want to generate visual graphs (e.g. in SVG or DOT format).
69
70### Mac OS X
71
72```sh
73brew install graphviz || port install graphviz
74```
75
76### Ubuntu
77
78```sh
79apt-get install graphviz
80```
81
82# API
83
84## madge(path: string|array|object, config: object)
85
86> `path` is a single file or directory, or an array of files/directories to read. A predefined tree can also be passed in as an object.
87
88> `config` is optional and should be the [configuration](#configuration) to use.
89
90> Returns a `Promise` resolved with the Madge instance object.
91
92## Functions
93
94#### .obj()
95
96> Returns an `Object` with all dependencies.
97
98```javascript
99const madge = require('madge');
100
101madge('path/to/app.js').then((res) => {
102 console.log(res.obj());
103});
104```
105
106#### .warnings()
107
108> Returns an `Object` of warnings.
109
110```javascript
111const madge = require('madge');
112
113madge('path/to/app.js').then((res) => {
114 console.log(res.warnings());
115});
116```
117
118#### .circular()
119
120> Returns an `Array` of all modules that has circular dependencies.
121
122```javascript
123const madge = require('madge');
124
125madge('path/to/app.js').then((res) => {
126 console.log(res.circular());
127});
128```
129
130#### .depends()
131
132> Returns an `Array` of all modules that depend on a given module.
133
134```javascript
135const madge = require('madge');
136
137madge('path/to/app.js').then((res) => {
138 console.log(res.depends('lib/log.js'));
139});
140```
141
142#### .orphans()
143
144> Return an `Array` of all modules that no one is depending on.
145
146```javascript
147const madge = require('madge');
148
149madge('path/to/app.js').then((res) => {
150 console.log(res.orphans());
151});
152```
153
154#### .leaves()
155
156> Return an `Array` of all modules that have no dependencies.
157
158```javascript
159const madge = require('madge');
160
161madge('path/to/app.js').then((res) => {
162 console.log(res.leaves());
163});
164```
165
166#### .dot()
167
168> Returns a `Promise` resolved with a DOT representation of the module dependency graph.
169
170```javascript
171const madge = require('madge');
172
173madge('path/to/app.js')
174 .then((res) => res.dot())
175 .then((output) => {
176 console.log(output);
177 });
178```
179
180#### .image(imagePath: string)
181
182> Write the graph as an image to the given image path. The [image format](http://www.graphviz.org/content/output-formats) to use is determined from the file extension. Returns a `Promise` resolved with a full path to the written image.
183
184```javascript
185const madge = require('madge');
186
187madge('path/to/app.js')
188 .then((res) => res.image('path/to/image.svg'))
189 .then((writtenImagePath) => {
190 console.log('Image written to ' + writtenImagePath);
191 });
192```
193
194#### .svg()
195
196> Return a `Promise` resolved with the XML SVG representation of the dependency graph as a `Buffer`.
197
198```javascript
199const madge = require('madge');
200
201madge('path/to/app.js')
202 .then((res) => res.svg())
203 .then((output) => {
204 console.log(output.toString());
205 });
206```
207
208# Configuration
209
210Property | Type | Default | Description
211--- | --- | --- | ---
212`baseDir` | String | null | Base directory to use instead of the default
213`includeNpm` | Boolean | false | If shallow NPM modules should be included
214`fileExtensions` | Array | ['js'] | Valid file extensions used to find files in directories
215`excludeRegExp` | Array | false | An array of RegExp for excluding modules
216`requireConfig` | String | null | RequireJS config for resolving aliased modules
217`webpackConfig` | String | null | Webpack config for resolving aliased modules
218`tsConfig` | String\|Object | null | TypeScript config for resolving aliased modules - Either a path to a tsconfig file or an object containing the config
219`layout` | String | dot | Layout to use in the graph
220`rankdir` | String | LR | Sets the [direction](https://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rankdir) of the graph layout
221`fontName` | String | Arial | Font name to use in the graph
222`fontSize` | String | 14px | Font size to use in the graph
223`backgroundColor` | String | #000000 | Background color for the graph
224`nodeShape` | String | box | A string specifying the [shape](https://graphviz.gitlab.io/_pages/doc/info/attrs.html#k:shape) of a node in the graph
225`nodeStyle` | String | rounded | A string specifying the [style](https://graphviz.gitlab.io/_pages/doc/info/attrs.html#k:style) of a node in the graph
226`nodeColor` | String | #c6c5fe | Default node color to use in the graph
227`noDependencyColor` | String | #cfffac | Color to use for nodes with no dependencies
228`cyclicNodeColor` | String | #ff6c60 | Color to use for circular dependencies
229`edgeColor` | String | #757575 | Edge color to use in the graph
230`graphVizOptions` | Object | false | Custom Graphviz [options](https://graphviz.gitlab.io/_pages/doc/info/attrs.html)
231`graphVizPath` | String | null | Custom Graphviz path
232`detectiveOptions` | Object | false | Custom `detective` options for [dependency-tree](https://github.com/dependents/node-dependency-tree) and [precinct](https://github.com/dependents/node-precinct#usage)
233`dependencyFilter` | Function | false | Function called with a dependency filepath (exclude substree by returning false)
234
235You can use configuration file either in `.madgerc` in your project or home folder or directly in `package.json`. Look [here](https://github.com/dominictarr/rc#standards) for alternative locations for the file.
236
237> .madgerc
238
239```json
240{
241 "fontSize": "10px",
242 "graphVizOptions": {
243 "G": {
244 "rankdir": "LR"
245 }
246 }
247}
248```
249
250> package.json
251```json
252{
253 "name": "foo",
254 "version": "0.0.1",
255 ...
256 "madge": {
257 "fontSize": "10px",
258 "graphVizOptions": {
259 "G": {
260 "rankdir": "LR"
261 }
262 }
263 }
264}
265```
266
267# CLI
268
269## Examples
270
271> List dependencies from a single file
272
273```sh
274madge path/src/app.js
275```
276
277> List dependencies from multiple files
278
279```sh
280madge path/src/foo.js path/src/bar.js
281```
282
283> List dependencies from all *.js files found in a directory
284
285```sh
286madge path/src
287```
288
289> List dependencies from multiple directories
290
291```sh
292madge path/src/foo path/src/bar
293```
294
295> List dependencies from all *.js and *.jsx files found in a directory
296
297```sh
298madge --extensions js,jsx path/src
299```
300
301> Finding circular dependencies
302
303```sh
304madge --circular path/src/app.js
305```
306
307> Show modules that depends on a given module
308
309```sh
310madge --depends wheels.js path/src/app.js
311```
312
313> Show modules that no one is depending on
314
315```sh
316madge --orphans path/src/
317```
318
319> Show modules that have no dependencies
320
321```sh
322madge --leaves path/src/
323```
324
325> Excluding modules
326
327```sh
328madge --exclude '^(foo|bar)\.js$' path/src/app.js
329```
330
331> Save graph as a SVG image (requires [Graphviz](#graphviz-optional))
332
333```sh
334madge --image graph.svg path/src/app.js
335```
336
337> Save graph as a [DOT](http://en.wikipedia.org/wiki/DOT_language) file for further processing (requires [Graphviz](#graphviz-optional))
338
339```sh
340madge --dot path/src/app.js > graph.gv
341```
342
343> Using pipe to transform tree (this example will uppercase all paths)
344
345```sh
346madge --json path/src/app.js | tr '[a-z]' '[A-Z]' | madge --stdin
347```
348
349# Debugging
350
351> To enable debugging output if you encounter problems, run madge with the `--debug` option then throw the result in a gist when creating issues on GitHub.
352
353```sh
354madge --debug path/src/app.js
355```
356
357# Running tests
358
359```sh
360npm install
361npm test
362```
363
364# FAQ
365
366## Missing dependencies?
367
368It could happen that the files you're not seeing have been skipped due to errors or that they can't be resolved. Run madge with the `--warning` option to see skipped files. If you need even more info run with the `--debug` option.
369
370## Using both Javascript and Typescript in your project?
371
372Madge uses [dependency-tree](https://www.npmjs.com/package/dependency-tree) which uses [filing-cabinet](https://www.npmjs.com/package/filing-cabinet) to resolve modules. However it requires configurations for each file type (js/jsx) and (ts/tsx). So provide both `webpackConfig` and `tsConfig` options to madge.
373
374## Using mixed import syntax in the same file?
375
376Only one syntax is used by default. You can use both though if you're willing to take the degraded performance. Put this in your madge config to enable mixed imports.
377
378For ES6 + CommonJS:
379```json
380{
381 "detectiveOptions": {
382 "es6": {
383 "mixedImports": true
384 }
385 }
386}
387```
388
389For TypeScript + CommonJS:
390```json
391{
392 "detectiveOptions": {
393 "ts": {
394 "mixedImports": true
395 }
396 }
397}
398```
399
400## How to ignore `import type` statements in ES6 + Flow?
401
402Put this in your madge config.
403
404```json
405{
406 "detectiveOptions": {
407 "es6": {
408 "skipTypeImports": true
409 }
410 }
411}
412```
413
414## How to ignore `import` in type annotations in TypeScript?
415
416Put this in your madge config.
417
418```json
419{
420 "detectiveOptions": {
421 "ts": {
422 "skipTypeImports": true
423 }
424 }
425}
426```
427
428## What's the "Error: write EPIPE" when exporting graph to image?
429
430Ensure you have [installed Graphviz](#graphviz-optional). If you're running Windows, note that Graphviz is not added to the `PATH` variable during install. You should add the folder of `gvpr.exe` (typically `%Graphviz_folder%/bin`) to the `PATH` variable manually.
431
432## How do I fix the "Graphviz not built with triangulation library" error when using sfdp layout?
433
434Homebrew doesn't include GTS by default. Fix this by doing:
435
436```sh
437brew uninstall graphviz
438brew install gts
439brew install graphviz
440```
441
442## The image produced by madge is very hard to read, what's wrong?
443
444Try running madge with a different layout, here's a list of the ones you can try:
445
446* **dot** "hierarchical" or layered drawings of directed graphs. This is the default tool to use if edges have directionality.
447
448* **neato** "spring model'' layouts. This is the default tool to use if the graph is not too large (about 100 nodes) and you don't know anything else about it. Neato attempts to
449minimize a global energy function, which is equivalent to statistical multi-dimensional scaling.
450
451* **fdp** "spring model'' layouts similar to those of neato, but does this by reducing forces rather than working with energy.
452
453* **sfdp** multiscale version of fdp for the layout of large graphs.
454
455* **twopi** radial layouts, after Graham Wills 97. Nodes are placed on concentric circles depending their distance from a given root node.
456
457* **circo** circular layout, after Six and Tollis 99, Kauffman and Wiese 02. This is suitable for certain diagrams of multiple cyclic structures, such as certain telecommunications networks.
458
459# Credits
460
461## Contributors
462
463This project exists thanks to all the people who contribute.
464<a href="https://github.com/pahen/madge/graphs/contributors"><img src="https://opencollective.com/madge/contributors.svg?width=890&button=false" alt="Contributors"/></a>
465
466## Donations ❤️
467
468Thanks to the awesome people below for making donations! 🙏[[Donate](https://paypal.me/pahen)]
469
470**Landon Alder**
471
472<a href="https://github.com/landonalder" target="_blank">
473 <img src="https://github.com/landonalder.png" width="64"/>
474</a>
475
476**Peter Verswyvelen**
477
478<a href="https://github.com/Ziriax" target="_blank">
479 <img src="https://github.com/Ziriax.png" width="64"/>
480</a>
481
482**RxDB**
483
484<a href="https://github.com/pubkey/rxdb">
485 <img src="https://cdn.rawgit.com/pubkey/rxdb/ba7c9b80/docs/files/logo/logo_text.svg" width="128" style="margin-left: -10px"/>
486</a>
487
488# License
489
490MIT License