pahen / madge

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

running madge from outside project directory shows empty dependencies with paths tsconfig option #430

Open dyllandry opened 2 months ago

dyllandry commented 2 months ago

Minimal reproducible example: https://github.com/dyllandry/vite-madge-mre

When working on a vue project and running madge from outside the project directory, madge shows missing imports when the import uses tsconfig's paths option.

This will correctly work when madge is run from inside the project:

$ ../madge/bin/cli.js src/main.js --ts-config tsconfig.json 
Processed 4 files (352ms) 

App.vue
  components/HelloWorld.vue
components/HelloWorld.vue
main.js
  App.vue
  style.css
style.css

But when run from outside the project, it doesn't work:

$ ./madge/bin/cli.js vite-madge-mre/src/main.js --ts-config vite-madge-mre/tsconfig.json --warning
Processed 3 files (272ms) (1 warning)

App.vue
main.js
  App.vue
  style.css
style.css

✖ Skipped 1 file

@/components/HelloWorld.vue

I've seen this issue https://github.com/pahen/madge/issues/399 but I'm not sure what they set --basedir to to get it working. I've tried many different combinations.

I've gotten it working by setting in the project's tsconfig "baseUrl": "." but that could cause breaking behaviour in the project by favoring a relative import instead of one from node_modules.

dyllandry commented 2 months ago

My current solution is when calling the madge module to provide a tsconfig object that uses my project's tsconfig and adds a baseUrl set to the path to the project's directory.

  const madgeResult = await madge(pathToMainJs, {
    baseDir: pathToProjectDir,
    tsConfig: {
      ...projectsTsconfig,
      compilerOptions: {
        ...projectsTsconfig.compilerOptions,
        baseUrl: pathToProjectDir,
      },
    },
  });

This works for now, but it can still cause breaking changes. If I understand the baseUrl docs correctly, if the project imports "my-module" it could now resolve to a local file "my-module.js" when they mean for it to resolve to a package in node_modules called "my-module". I don't think this is happening for any of my projects, but it is a reason why this solution isn't ideal.