pahen / madge

Create graphs from your CommonJS, AMD or ES6 module dependencies
MIT License
8.96k stars 318 forks source link

Graphs are unreadable past 15 dependencies #289

Open fregante opened 3 years ago

fregante commented 3 years ago

Hi! This is a great tool but I'm struggling to make it useful. Graphs are not a great way to represent dependencies because shared dependencies are pulled so far right and away from their importers, forcing you to follow thousands of pixels of lines.

a

The entry point has 6 direct dependencies, can you spot them in less than 10 seconds? 10 seconds is a long time to spot 6 dependencies.

The solution here is to use the textual output and that cleanly shows you the 6 dependencies… if you only find the entry point in this list in alphabetical order:

auth/token.ts
  ../node_modules/fast-deep-equal/index.js
  ../node_modules/js-cookie/src/js.cookie.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  chrome.ts
  telemetry/rollbar.ts
background/logging.ts
  ../node_modules/idb/with-async-ittr.js
  ../node_modules/lodash/lodash.js
  ../node_modules/serialize-error/index.js
  ../node_modules/type-fest/index.d.ts
  ../node_modules/uuid/dist/index.js
  ../node_modules/webext-detect-page/index.js
  background/protocol.ts
  background/telemetry.ts
  chrome.ts
  contentScript/connection.ts
  core.ts
  errors.ts
  telemetry/rollbar.ts
  utils/expectContext.ts
background/popup.ts
  ../node_modules/webextension-polyfill-ts/lib/index.js
  background/protocol.ts
  helpers.ts
  utils/expectContext.ts
background/protocol.ts
  ../node_modules/serialize-error/index.js
  ../node_modules/uuid/dist/index.js
  ../node_modules/webext-detect-page/index.js
  ../node_modules/webext-patterns/index.js
  ../node_modules/webext-polyfill-kinda/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  chrome.ts
  messaging/protocol.ts
background/telemetry.ts
  ../node_modules/axios/index.js
  ../node_modules/lodash/lodash.js
  ../node_modules/type-fest/index.d.ts
  ../node_modules/uuid/dist/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  auth/token.ts
  background/protocol.ts
  chrome.ts
  options/loader.ts
  services/baseService.ts
  utils.ts
chrome.ts
  ../node_modules/lodash/isEmpty.js
  ../node_modules/p-defer/index.js
  ../node_modules/p-timeout/index.js
  ../node_modules/webext-detect-page/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  utils/expectContext.ts
components/AsyncButton.tsx
  ../node_modules/react-bootstrap/cjs/Button.js
  ../node_modules/react/index.js
contentScript/backgroundProtocol.ts
  ../node_modules/serialize-error/index.js
  ../node_modules/webext-detect-page/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  errors.ts
  messaging/protocol.ts
  utils/expectContext.ts
contentScript/connection.ts
  contentScript/notify.ts
contentScript/notify.ts
  ../node_modules/lodash/lodash.js
  contentScript/backgroundProtocol.ts
core.ts
  ../node_modules/@rjsf/core/dist/cjs/index.js
  ../node_modules/@types/json-schema/index.d.ts
  ../node_modules/axios/index.js
  ../node_modules/lodash/lodash.js
  ../node_modules/serialize-error/index.js
  ../node_modules/type-fest/index.d.ts
  ../node_modules/webextension-polyfill-ts/lib/index.js
devTools/editor/components/Centered.tsx
  ../node_modules/react-bootstrap/cjs/index.js
  ../node_modules/react/index.js
errors.ts
  ../node_modules/serialize-error/index.js
  core.ts
extensionContext.ts
  ../node_modules/webextension-polyfill-ts/lib/index.js
helpers.ts
  ../node_modules/handlebars/lib/index.js
  ../node_modules/lodash/isPlainObject.js
  ../node_modules/lodash/mapKeys.js
  ../node_modules/lodash/mapValues.js
  ../node_modules/lodash/pickBy.js
  ../node_modules/mustache/mustache.js
  ../node_modules/nunjucks/index.js
  core.ts
  utils.ts
messaging/protocol.ts
  ../node_modules/is-promise/index.js
  ../node_modules/serialize-error/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  core.ts
options/loader.ts
  ../node_modules/type-fest/index.d.ts
  ../node_modules/webextension-polyfill-ts/lib/index.js
  core.ts
permissionsPopup.tsx
  ../node_modules/bootstrap/dist/css/bootstrap.min.css
  ../node_modules/react-dom/index.js
  ../node_modules/react/index.js
  extensionContext.ts
  popups/PermissionsPopup.tsx
  telemetry/rollbar.ts
popups/PermissionsPopup.tsx
  ../node_modules/@fortawesome/free-solid-svg-icons/index.js
  ../node_modules/@fortawesome/react-fontawesome/index.js
  ../node_modules/react-bootstrap/cjs/index.js
  ../node_modules/react/index.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  components/AsyncButton.tsx
  devTools/editor/components/Centered.tsx
  errors.ts
  telemetry/logging.ts
  utils/permissions.ts
services/baseService.ts
  ../node_modules/lodash/isEmpty.js
  ../node_modules/react/index.js
  ../node_modules/use-async-effect/index.js
  chrome.ts
telemetry/logging.ts
  ../node_modules/serialize-error/index.js
  ../node_modules/webext-detect-page/index.js
  background/logging.ts
  chrome.ts
  core.ts
  telemetry/rollbar.ts
telemetry/rollbar.ts
  ../node_modules/rollbar/src/server/rollbar.js
  background/telemetry.ts
  chrome.ts
utils.ts
  ../node_modules/lodash/lodash.js
  ../node_modules/type-fest/index.d.ts
utils/expectContext.ts
  ../node_modules/webext-detect-page/index.js
utils/permissions.ts
  ../node_modules/lodash/groupBy.js
  ../node_modules/lodash/sortBy.js
  ../node_modules/lodash/uniq.js
  ../node_modules/webextension-polyfill-ts/lib/index.js
  background/popup.ts
  background/protocol.ts

Additionally the list is monodimensional: I can see the 6 dependencies, but then I can't follow them easily.

fregante commented 3 years ago

If you're familiar with macOS, this should give you a good idea of how I'd expect to be able to explore the dependencies in a project:

Screen Shot 1

It gives you a clear view of each dependency and sub dependency:

It's interactive but doesn't have to be: Shared dependencies can just end with a symbol, e.g. chrome.ts above could just show a non-linked extensionContext.ts item, which is on the second level already.

fregante commented 3 years ago

I just realized that I can get what I'm suggesting by just opening each file and reading its import statements 🤔

What that lacks though is the ability to see the dependency branch (i.e. not just one list of imports at a time, but both the parents and the children of each dependency, like in the Finder screenshot above)

PabloLION commented 1 year ago

seems hard to do. what about we make the graph "reactive" and nodes and expand / collapse by clicking them?