madge
madge copied to clipboard
v6.0.0: Circular Dependencies with only one node?
I run madge in my pipelines as a spaghetti mitigation strategy.
Using madge 5, everything went swimmingly
$ npx -p madge@5 madge -c --ts-config tsconfig.json --extensions ts --warning .
Processed 23 files (515ms)
✔ No circular dependency found!
Madge 6, and there comes warnings and a failure
$ npx -p madge@6 madge -c --ts-config tsconfig.json --extensions ts --warning .
Processed 23 files (575ms) (2 warnings)
✖ Found 1 circular dependency!
1) lib/focus.ts
✖ Skipped 2 files
./lib
../lib
I tried generating a graph to see where Madge 6 saw something new. Madge 5 prints a graph where all is good.
Madge 6 prints Processed 23 files (575ms) (2 warnings)
then exits...
Can't tell what went wrong yet, but it feels like v6 broke something related to
import { stuff } from './lib'
So I ran madge@6 in a debugger...
my lib/focus.ts
file starts with
import type { HardwareType, IAttachmentManifest, ProductType } from "focus";
import type { AnyPayload, ILegacyPayload } from "../interface";
import { isLegacyPayload } from "./legacy_guard";
focus
is an internal package we defined in our own @types/focus
the result.tree
of createOutputFromOptions
contains the following
[
"interface.d.ts",
"lib/focus.ts",
"lib/legacy_guard.ts",
]
So, import {x} from 'focus'
got mangled up as lib/focus.ts
in there...
The whole tree seems to mistake a file for the package...
(snipped for relevant files)
{
"lib/ab.ts": [
"interface.d.ts",
"lib/focus.ts",
"lib/hackson_guards.ts",
"lib/util.ts",
],
"lib/awc.ts": [
"lib/focus.ts",
],
"lib/focus.ts": [
"interface.d.ts",
"lib/focus.ts",
"lib/legacy_guard.ts",
],
"lib/index.ts": [
"lib/ab.ts",
"lib/awc.ts",
"lib/focus.ts",
"lib/hackson_guards.ts",
"lib/legacy_guard.ts",
"lib/ob.ts",
"lib/temperature.ts",
"lib/ub.ts",
"lib/util.ts",
],
"lib/ob.ts": [
"interface.d.ts",
"lib/focus.ts",
"lib/hackson_guards.ts",
"lib/util.ts",
],
"lib/temperature.ts": [
"interface.d.ts",
"lib/focus.ts",
"lib/hackson_guards.ts",
],
"lib/ub.ts": [
"interface.d.ts",
"lib/focus.ts",
"lib/hackson_guards.ts",
"lib/util.ts",
],
"lib/util.ts": [
"lib/focus.ts",
],
}
The only file that should really refer to lib/focus.ts
is lib/index.ts
. All the others import from the focus
package
@carboneater Thanks for reporting!
Although a detailed investigation has not yet been done, it appears that the behavior of the dependent libraries has changed, as the algorithm for generating the source code dependency tree has not changed.
https://github.com/pahen/madge/compare/v5.0.2...v6.0.0
Whether to raise this as an issue to the dependent libraries or to take it special care of it in this library needs to be discussed.
I'm also experiencing false positives for circular dependencies in version 6 which were fine in version 5. Two of our files that do not import each other are reported as a circular dependency.
Update: it's failing for us because of our path aliases in tsconfig.json
as @mx-bernhard mentions below.
This seems to be the same problem that also causes #271 and the workaround that I've written there should also make the wrong resolutions disappear.
FYI, the critical values that should be present in "tsConfig" entry is "moduleResolution": "node"
:
"madge": {
"baseDir": "./server",
"fileExtensions": ["ts"],
"tsConfig": {
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext", "dom"],
"moduleResolution": "node"
},
yeah we are also experiencing these false positives in a case where we have a local file (utils/analytics.ts
) with the same name as a npm package (analytics
) that we import with the exact same name in that file
Have you tried to define "moduleResolution": "node"
as per my previous entry? It has solved the problem for me.
Have you tried to define
"moduleResolution": "node"
as per my previous entry? It has solved the problem for me.
yes we had that set up already in our tsconfig
Sorry to ask @bartvde but also with the tsConfig addition to "madge" section the problem is still there?
if I set the respective config in package.json for madge it seems to work, but not when I pass in the tsconfig which has moduleResolution set to node (--ts-config=tsconfig.json
)
Yes, there is something strange when you read a tsconfig.json
compared to copying its content inside the madge
section of package.json
. For this I put a minimal tsconfig as per https://github.com/pahen/madge/issues/355#issuecomment-1475944946