Closed swachter closed 7 months ago
Hi @swachter thanks for reaching out! I would expect this to work out of the box, so I'm curious what's going on exactly. Do you have an example (doesn't have to be the complete repository, a small reproduction sample would already be helpful).
Hi @sverweij many thanks for looking into this!
I prepared a repo with a minimized reproduction sample.
Thanks @swachter that was very helpful!
It took a bit to wrap my head around the setup, but once it had and I viewed the graph understanding dawned:
src/index.mts
imports the transpiled constants.mjs from the @monorepo/utils/resources
package and not the typescript file it originates from. As a consequence the TypeScript source will indeed never be imported, which technically makes it an orphan, even though conceptually it isn't - it was used to generate out/constants.mjs
.
node_modules/@monorepo/utils
. It's symlinked to packages/utils
so it'll look over there.package.json
package.json
it finds an exports
key and the instruction to get imports from the ./out/
folder in packages/utils/
resources/constants.mjs
in packages/utils/out
packages/utils/out/constants.mjs
exists => resolution done.I guess that in the symlinked workspaces setup it is an expected pattern to only export the compiled-to-javascript dist files of packages and not the original sources?
Does it make sense, knowing the above, that index.mts depends on the compiled constants.mjs?
I do understand that for a conceptual overview you still might want to see links/ dependencies to the original TypeScript. If so:
packages/utils/package.json
, and finding the original TypeScript otherwise seems non-trivial. I'm open to suggestions, though!package/utils/package.json
and in .dependency-cruiser.cjs
:
exports
field of the package/utils/package.json
that tells where the sources live (e.g. imports-source
). Put that one before the imports
condition.diff --git a/.dependency-cruiser.cjs b/.dependency-cruiser.cjs
index 1696d4e..30c6d62 100644
--- a/.dependency-cruiser.cjs
+++ b/.dependency-cruiser.cjs
@@ -316,7 +316,7 @@ module.exports = {
/* List of conditions to check for in the exports field.
Only works when the 'exportsFields' array is non-empty.
*/
- conditionNames: ["import", "require", "node", "default", "types"],
+ conditionNames: ["source-import", "import", "require", "node", "default", "types"],
/*
The extensions, by default are the same as the ones dependency-cruiser
can access (run `npx depcruise --info` to see which ones that are in
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 6f78013..a1d1ae1 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -14,6 +14,7 @@
"type": "module",
"exports": {
"./*": {
+ "source-import": "./src/*.mts",
"import": "./out/*.mjs",
"types": "./out/*.d.mts"
}
Another workaround, for completeness sake only
If you'd want to export the TypeScript source instead of its compiled version (which I don't expect you do ...) you can update the exports clause in
packages/utils/
to references thesrc
files.diff --git a/packages/utils/package.json b/packages/utils/package.json index 6f78013..a1d1ae1 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -14,6 +14,7 @@ "type": "module", "exports": { "./*": { - "import": "./out/*.mjs", + "import": "./src/*.mts", "types": "./out/*.d.mts" }
Many thanks for the analysis! I understand that a general mechanism for detecting such indirect dependencies would be complicated. I assume it would be necessary to consider what output directories are configured for tsc
and how these outputs are exported. Could source maps come to the rescue here?
However, for now I will proceed with your suggested workaround with the extra export condition.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
When workspaces are used, NPM symlinks workspace folders into the
node_modules
folder. If corresponding dependencies are defined inpackage.json
of the root project then files can be imported using these "workspace dependencies".When a mono repo is analyzed e.g. by
depcruise src packages/*/src
then files in workspaces that are imported using such "workspace dependencies" are reported as orphans.Expected Behavior
Dependency cruiser should recognize that imports from "workspace dependencies" target files in workspaces.
Current Behavior
Files in workspaces that are imported in the main sources by "workspace dependencies" only, count as orphans.