diff --git a/README.md b/README.md index 829aa86de..516a38add 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,31 @@ -# dependency cruiser -Visualize and javascript dependencies against your own rules. ES6, CommonJS, AMD. +# Dependency cruiser ![Dependency cruiser](doc/assets/ZKH-Dependency-recolored-160.png) +_Visualize and validate javascript dependencies. With your rules._ ES6, CommonJS, AMD. + +![Snazzy dot output to whet your appetite](doc/assets/sample-dot-output.png) + +## Installation +Dependency cruiser works most comfortably if you install it globally +``` +npm install --global dependency-cruiser +``` + +## Daphne's dependencies - a gentle introduction +Head over to **[Daphne's dependencies](doc/sample-output.md)** to get an +overview of all the output formats. And how Daphne uses it all. And how she +uses the awesome _validation_ in her workflow. Go on. Read it. Or would you +rather prefer continue the boring recount of a README written with _reference +doc_ in mind? + +## Basic usage +To dump all the dependencies in `src` to into a dependency matrix you can +open in your browser: + +```shell +dependency-cruise -T html -f deps.html src +``` + +Running with no parameters gets you help: ``` Usage: dependency-cruise [options] @@ -16,20 +41,6 @@ Options: -r, --rules-file read rules from (default: .dependency-cruiser.json) ``` -## Installation -Dependency cruiser works most comfortably if you install it globally - -``` -npm install --global dependency-cruiser -``` - -## Basic usage -To dump all the dependencies in `src` to stdout in json format: - -```shell -dependency-cruise src -``` - ## Output formats ### html Write it to html with a dependency matrix instead: @@ -46,9 +57,6 @@ and analyze from there. Supplying `dot` as output type will make dependency-cruiser write a GraphViz dot format directed graph. -### json -The default. - ### err For use in build scripts, in combination with `--validate` and/ or `--rules-file` e.g. @@ -131,13 +139,11 @@ A more elaborate configuration: } ``` - ### --rules-file implies --validate Because if you supply a rules file, you probably intend them to be used in validation, dependency-cruiser assumes `--validate` to be passed even if it wasn't. - ## License [MIT](LICENSE) diff --git a/doc/assets/ZKH-Dependency-recolored-160.png b/doc/assets/ZKH-Dependency-recolored-160.png new file mode 100644 index 000000000..c5385f9e4 Binary files /dev/null and b/doc/assets/ZKH-Dependency-recolored-160.png differ diff --git a/doc/assets/ZKH-Dependency-recolored-320.png b/doc/assets/ZKH-Dependency-recolored-320.png new file mode 100644 index 000000000..1271225b8 Binary files /dev/null and b/doc/assets/ZKH-Dependency-recolored-320.png differ diff --git a/doc/assets/ZKH-Dependency-recolored-320.svg b/doc/assets/ZKH-Dependency-recolored-320.svg new file mode 100644 index 000000000..5f4e42993 --- /dev/null +++ b/doc/assets/ZKH-Dependency-recolored-320.svg @@ -0,0 +1,86 @@ + + + + +Created by potrace 1.13, written by Peter Selinger 2001-2015 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/assets/sample-csv-output.csv b/doc/assets/sample-csv-output.csv new file mode 100644 index 000000000..ebb498617 --- /dev/null +++ b/doc/assets/sample-csv-output.csv @@ -0,0 +1,9 @@ +"","test/fixtures/cjs/one_only_one.js","test/fixtures/cjs/one_only_two.js","test/fixtures/cjs/root_one.js","test/fixtures/cjs/root_two.js","test/fixtures/cjs/shared.js","test/fixtures/cjs/sub/depindir.js","test/fixtures/cjs/sub/dir.js","test/fixtures/cjs/two_only_one.js","" +"test/fixtures/cjs/one_only_one.js","false","false","false","false","false","false","false","false","" +"test/fixtures/cjs/one_only_two.js","false","false","false","false","false","false","false","false","" +"test/fixtures/cjs/root_one.js","true","true","false","false","true","false","violation","false","" +"test/fixtures/cjs/root_two.js","false","false","false","false","true","false","false","true","" +"test/fixtures/cjs/shared.js","false","false","false","false","false","false","false","false","" +"test/fixtures/cjs/sub/depindir.js","false","false","false","false","false","false","false","false","" +"test/fixtures/cjs/sub/dir.js","false","false","false","false","false","violation","false","false","" +"test/fixtures/cjs/two_only_one.js","false","false","false","false","false","false","violation","false","" diff --git a/doc/assets/sample-csv-output.png b/doc/assets/sample-csv-output.png new file mode 100644 index 000000000..0add88709 Binary files /dev/null and b/doc/assets/sample-csv-output.png differ diff --git a/doc/assets/sample-dot-output.png b/doc/assets/sample-dot-output.png new file mode 100644 index 000000000..8b9a59a8d Binary files /dev/null and b/doc/assets/sample-dot-output.png differ diff --git a/doc/assets/sample-err-output.txt b/doc/assets/sample-err-output.txt new file mode 100644 index 000000000..212ada62b --- /dev/null +++ b/doc/assets/sample-err-output.txt @@ -0,0 +1,4 @@ +Dependency-cruiser found the following illegal dependencies: + test/fixtures/cjs/root_one.js => test/fixtures/cjs/sub/dir.js + test/fixtures/cjs/sub/dir.js => test/fixtures/cjs/sub/depindir.js + test/fixtures/cjs/two_only_one.js => test/fixtures/cjs/sub/dir.js diff --git a/doc/assets/sample-html-output.html b/doc/assets/sample-html-output.html new file mode 100644 index 000000000..0adbfc036 --- /dev/null +++ b/doc/assets/sample-html-output.html @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ rotate + rotate back +
test/fixtures/cjs/one_only_one.js
test/fixtures/cjs/one_only_two.js
test/fixtures/cjs/root_one.js
test/fixtures/cjs/root_two.js
test/fixtures/cjs/shared.js
test/fixtures/cjs/sub/depindir.js
test/fixtures/cjs/sub/dir.js
test/fixtures/cjs/two_only_one.js
test/fixtures/cjs/one_only_one.jstest/fixtures/cjs/one_only_one.js
test/fixtures/cjs/one_only_two.jstest/fixtures/cjs/one_only_two.js
test/fixtures/cjs/root_one.jstest/fixtures/cjs/root_one.js
test/fixtures/cjs/root_two.jstest/fixtures/cjs/root_two.js
test/fixtures/cjs/shared.jstest/fixtures/cjs/shared.js
test/fixtures/cjs/sub/depindir.jstest/fixtures/cjs/sub/depindir.js
test/fixtures/cjs/sub/dir.jstest/fixtures/cjs/sub/dir.js
test/fixtures/cjs/two_only_one.jstest/fixtures/cjs/two_only_one.js
test/fixtures/cjs/one_only_one.js
test/fixtures/cjs/one_only_two.js
test/fixtures/cjs/root_one.js
test/fixtures/cjs/root_two.js
test/fixtures/cjs/shared.js
test/fixtures/cjs/sub/depindir.js
test/fixtures/cjs/sub/dir.js
test/fixtures/cjs/two_only_one.js
diff --git a/doc/assets/sample-html-output.png b/doc/assets/sample-html-output.png new file mode 100644 index 000000000..bb169da40 Binary files /dev/null and b/doc/assets/sample-html-output.png differ diff --git a/doc/assets/sample-html-rotated-output.png b/doc/assets/sample-html-rotated-output.png new file mode 100644 index 000000000..1e7f3814a Binary files /dev/null and b/doc/assets/sample-html-rotated-output.png differ diff --git a/doc/assets/sample-json-output.json b/doc/assets/sample-json-output.json new file mode 100644 index 000000000..b0fb3e6e8 --- /dev/null +++ b/doc/assets/sample-json-output.json @@ -0,0 +1,207 @@ +[ + { + "source": "test/fixtures/cjs/node_modules/somemodule/node_modules/someothermodule/main.js", + "dependencies": [] + }, + { + "source": "test/fixtures/cjs/node_modules/somemodule/src/moar-javascript.js", + "dependencies": [] + }, + { + "source": "test/fixtures/cjs/node_modules/somemodule/src/somemodule.js", + "dependencies": [ + { + "module": "./moar-javascript", + "resolved": "test/fixtures/cjs/node_modules/somemodule/src/moar-javascript.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "someothermodule", + "resolved": "test/fixtures/cjs/node_modules/somemodule/node_modules/someothermodule/main.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/one_only_one.js", + "dependencies": [ + { + "module": "path", + "resolved": "path", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/one_only_two.js", + "dependencies": [ + { + "module": "path", + "resolved": "path", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/root_one.js", + "dependencies": [ + { + "module": "./one_only_one", + "resolved": "test/fixtures/cjs/one_only_one.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "./one_only_two", + "resolved": "test/fixtures/cjs/one_only_two.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "./shared", + "resolved": "test/fixtures/cjs/shared.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "./sub/dir", + "resolved": "test/fixtures/cjs/sub/dir.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": false + }, + { + "module": "fs", + "resolved": "fs", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + }, + { + "module": "somemodule", + "resolved": "test/fixtures/cjs/node_modules/somemodule/src/somemodule.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/shared.js", + "dependencies": [ + { + "module": "path", + "resolved": "path", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/sub/dir.js", + "dependencies": [ + { + "module": "./depindir", + "resolved": "test/fixtures/cjs/sub/depindir.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": false + }, + { + "module": "path", + "resolved": "path", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/sub/depindir.js", + "dependencies": [ + { + "module": "path", + "resolved": "path", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/root_two.js", + "dependencies": [ + { + "module": "./shared", + "resolved": "test/fixtures/cjs/shared.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "./somedata.json", + "resolved": "test/fixtures/cjs/somedata.json", + "moduleSystem": "cjs", + "coreModule": false, + "followable": false, + "valid": true + }, + { + "module": "./two_only_one", + "resolved": "test/fixtures/cjs/two_only_one.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": true + }, + { + "module": "http", + "resolved": "http", + "moduleSystem": "cjs", + "coreModule": true, + "followable": false, + "valid": true + } + ] + }, + { + "source": "test/fixtures/cjs/two_only_one.js", + "dependencies": [ + { + "module": "./sub/dir", + "resolved": "test/fixtures/cjs/sub/dir.js", + "moduleSystem": "cjs", + "coreModule": false, + "followable": true, + "valid": false + } + ] + } +] \ No newline at end of file diff --git a/doc/sample-output.md b/doc/sample-output.md new file mode 100644 index 000000000..f3518c958 --- /dev/null +++ b/doc/sample-output.md @@ -0,0 +1,86 @@ +# Daphne's dependencies +_A gentle introduction to dependency-cruiser_ + +Daphne is a software engineer. She works on a project where everything in a +folder called `sub` (not _her_ choice) got deprecated. So she adds rule to +the `.dependency-cruiser.json` in the root of her project: + +```json +{ + "forbidden":[{ + "from": ".+", + "to": "sub" + }] +} +``` +Dependencies from everywhere to the `sub` folder are _verboten_ from now on. :heart:. + +## dot +To get a feel of what she's in to, she runs a dep-cruise and runs the result +through dot. (_Daphne is like that. She and her command line: a *terrifying* +weapon._) +```sh +dependency-cruise -T dot -v test/fixtures | dot -T png > sample-dot-output.png +``` +![sample dot output](assets/sample-dot-output.png) + +## err +Her `Makefile` already has `dep-cruise` target, which is run as part of the +checks on her ci. (She also has a run script in her package.json, because her +colleagues like that, but she prefers `make` herself, it's just how she's wired) + +Low and behold - on the next push to her feature branch the build neatly fails. She +_loves_ how the exit code reflects the number of offending dependencies when +she uses the `err` output type: +```sh +dependency-cruise -T err -v test/fixtures +Dependency-cruiser found the following illegal dependencies: + test/fixtures/cjs/root_one.js => test/fixtures/cjs/sub/dir.js + test/fixtures/cjs/sub/dir.js => test/fixtures/cjs/sub/depindir.js + test/fixtures/cjs/two_only_one.js => test/fixtures/cjs/sub/dir.js +make: *** [dependency-cruise] Error 3 +``` + +(She also loves it how `-T err` just shuts up and stays out of the way +if there's nothing wrong.) + +So she gets on to refactor the code to obliterate those doubly blasted +modules in `sub`. + +## html +In the mean Alex, who's an architect in Daphne's project, gets a whiff of what +is afoot and heads over to the visual build output. + +The build server _knows_ it's architect, so it put a dependency report in a spot +where Alex can find it easily. This is the _command_: +```sh +dependency-cruise -T html -v -f stuff-for-alex/sample-dot-output.html test/fixtures +``` + +(_Actually the build server didn't. You know that. Build servers aren't that +nice. In fact that darn clever Daphne put it in her Makefile. Over where she +lets the coverage reporting happen. The build server just ran it blindly._) + +![sample html output](assets/sample-html-output.png) + +Alex gets a little cramp in her neck, just when she discovers +there's a tiny little _rotate_ button. That's better: +![sample html output - rotated](assets/sample-html-rotated-output.png) + +## csv +Daphne and Alex are covered. Their micro-managing spreadsheet hugging senior +environs, however, is not. Hence: comma separated values. In a file. So excel +(or LibreOffice) can chug it like it's 1999: + +```sh +dependency-cruise -T csv -v json -f sample-dot-output.csv test/fixtures +``` +![oldskool csv output. In a spreadsheet. Way out man!](assets/sample-csv-output.png) + +## json +This is there for the _persona_ 'Marty the maintainer', so he can debug things. +```sh +dependency-cruise -v -f sample-dot-output.json test/fixtures +``` +The result is rather voluminous, so here's just a link if you want to see it +[assets/sample-json-output.json](assets/sample-json-output.json).