sverweij / dependency-cruiser

Validate and visualize dependencies. Your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.
https://npmjs.com/dependency-cruiser
MIT License
5.37k stars 252 forks source link

Feature request: Resolve local path aliases in monorepos #565

Open ertrzyiks opened 2 years ago

ertrzyiks commented 2 years ago

First of all, thanks for the amazing tool! I find dependency-cruiser extremely helpful in my work.

Context

Here is an example repo that showcases a feature that is used in the one that I would like to analyze. https://github.com/ertrzyiks/dep-cruiser-ts-monorepo

It is a monorepo and the workspace a has a local path alias

Imports using this path alias are not resolved.

It works only if I add a global tsconfig.json to the root of the project

{
  "compilerOptions": {
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~core/*": ["packages/a/src/this-is-the-core/*"],
    }
  },
  "include": ["./packages"]
}

Expected Behavior

Imports are resolved using the closest tsconfig.json

Current Behavior

The workspace tsconfig.json is ignored

Possible Solution

Considered alternatives

Run dependency cruiser separately on each workspace

ertrzyiks commented 2 years ago

Maybe I should use TS projects instead 🤔

[edit] I tried to add a solution tsconfig to the root folder but it doesn't help

{
  "compilerOptions": {
    "noEmit": true
  },
  "references": [
    { "path": "./packages/a" },
    { "path": "./packages/b" }
  ],
  "files": []
}
daton89 commented 2 years ago

I'm also interested in this request, ts projects often uses paths to reference other packages. See Nx monorepo etc

neelance commented 2 years ago

We are also now using compilerOptions.paths to switch to absolute import paths. We would love to see this feature implemented.

For now we are using a patch:

diff --git a/node_modules/dependency-cruiser/src/extract/resolve/index.js b/node_modules/dependency-cruiser/src/extract/resolve/index.js
index a877690..62558e7 100644
--- a/node_modules/dependency-cruiser/src/extract/resolve/index.js
+++ b/node_modules/dependency-cruiser/src/extract/resolve/index.js
@@ -26,7 +26,7 @@ function resolveModule(
 ) {
   let lReturnValue = null;

-  const lStrippedModuleName = resolveHelpers.stripToModuleName(pModule.module);
+  const lStrippedModuleName = resolveHelpers.stripToModuleName(pModule.module.replace(/^~\//, `${pBaseDirectory}/src/`));
   if (
     isRelativeModuleName(lStrippedModuleName) ||
     ["cjs", "es6", "tsd"].includes(pModule.moduleSystem)
neelance commented 2 years ago

I now managed to solve this without resorting to a patch by using the webpackConfig option with a config file that only provides the resolve.alias option.