Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): improve packages recognition when the package version is an external package #29529

Merged

Conversation

newsiberian
Copy link
Contributor

Current Behavior

After updating from [email protected] to [email protected] our docusaurus dep starts blocking us from running any nx command because of the error described in the linked issue

The "nx/js/dependencies-and-lockfile" plugin threw an error while creating dependencies: Target project does not exist: npm:react-helmet-async@npm:@slorber/react-helmet-async@*

Expected Behavior

Packages with such deps, like: "react-helmet-async": "npm:@slorber/react-helmet-async@*" shouldn't break any nx command

Related Issue(s)

Fixes #27285

@newsiberian newsiberian requested a review from a team as a code owner January 6, 2025 20:57
@newsiberian newsiberian requested a review from Cammisuli January 6, 2025 20:57
Copy link

vercel bot commented Jan 6, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Updated (UTC)
nx-dev ⬜️ Ignored (Inspect) Visit Preview Feb 22, 2025 11:51am

Copy link

nx-cloud bot commented Jan 6, 2025

View your CI Pipeline Execution ↗ for commit 69027a1.

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 34m 47s View ↗
nx run-many -t check-imports check-commit check... ✅ Succeeded 15s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 2s View ↗
nx-cloud record -- nx format:check --base= --he... ✅ Succeeded 7s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 5s View ↗
nx documentation ✅ Succeeded 56s View ↗

☁️ Nx Cloud last updated this comment at 2025-02-24 15:12:58 UTC

@newsiberian
Copy link
Contributor Author

@Cammisuli can this PR be reviewed, please?

Copy link
Member

@Cammisuli Cammisuli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe having the npm specific checks in the project graph builder is the best place for this. The reason for this is that the builder itself should be technology/package agnostic. The project graph will contain much more types of external nodes than just npm. For example, there could be cargo, gradle, pip, etc.

We should fix the area that is actually adding the external nodes which would be in the js plugin here:

if (!lockFileNeedsReprocessing(lockFileHash)) {
const nodes = readCachedParsedLockFile().externalNodes;
parsedLockFile.externalNodes = nodes;
return {
externalNodes: nodes,
};
}
const externalNodes = getLockFileNodes(
packageManager,
lockFileContents,
lockFileHash,
context
);
parsedLockFile.externalNodes = externalNodes;
return {
externalNodes,
};

@newsiberian
Copy link
Contributor Author

newsiberian commented Feb 10, 2025

@Cammisuli , @meeroslav , hi, please, point me in a write direction. From what I understand the issue happens because of this line, which overrides the map key, so that key npm:react-helmet-async@npm:@slorber/react-helmet-async@* bacome npm:react-helmet-async and can't be found. At least by yarn classic and yarn 4 (basic setup).

My idea was to make a copy of external node (which has an "npm:" prefix in version) which leads to increase the number of external notes. In case of our app from 3271 to 3277. The final projectGraphDependencies isn't been changed (10400 records). But from what I understand the externalNodes is kind off dictionary map and it's not so painfully to increase the number of records within.

And my question wdyt about such solution. If I'm going in a wrong direction, please point me.

Subject: [PATCH] fix(core): improve packages recognition when version is and external
---
Index: nx-fork/packages/nx/src/plugins/js/lock-file/yarn-parser.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/nx-fork/packages/nx/src/plugins/js/lock-file/yarn-parser.ts b/nx-fork/packages/nx/src/plugins/js/lock-file/yarn-parser.ts
--- a/nx-fork/packages/nx/src/plugins/js/lock-file/yarn-parser.ts	(revision cb4a93e87217a99244160063b8993dc65d977716)
+++ b/nx-fork/packages/nx/src/plugins/js/lock-file/yarn-parser.ts	(date 1739214631533)
@@ -176,7 +176,12 @@
   for (const [packageName, versionMap] of nodes.entries()) {
     const hoistedNode = findHoistedNode(packageName, versionMap, combinedDeps);
     if (hoistedNode) {
-      hoistedNode.name = `npm:${packageName}`;
+      if (hoistedNode.data.version.startsWith('npm:')) {
+        const name = <const>`npm:${packageName}`;
+        versionMap.set(name, { ...hoistedNode, name });
+      } else {
+        hoistedNode.name = `npm:${packageName}`;
+      }
     }
 
     versionMap.forEach((node) => {

@Cammisuli
Copy link
Member

Cammisuli commented Feb 14, 2025

@newsiberian did you look at modifying the findVersion function here?

const version = findVersion(packageName, keysArray[0], snapshot, isBerry);

You can probably do additional checks in there to handle the npm: versioning there.

@newsiberian newsiberian force-pushed the graph-builder-npm-version-recognition branch from ae7459c to 5777536 Compare February 16, 2025 12:09
@newsiberian
Copy link
Contributor Author

You can probably do additional checks in there to handle the npm: versioning there.

thanks. Yes, I did some tweaks to allow parent func to know whether the node has an alias or not.

The important thing to note is that this code:

    if (hoistedNode) {
      hoistedNode.name = `npm:${packageName}`;
    }

actually affects on that map:

// we use key => node map to avoid duplicate work when parsing keys
let keyMap = new Map<string, ProjectGraphExternalNode>();

because they share the same nodes and first code, actually mutates the shared node. Which was quite unsuspected.

@Cammisuli
Copy link
Member

@newsiberian awesome! It looks good on my side. Rebase the PR to get the latest things from master, and then we can get this in. Thank you very much!

@newsiberian
Copy link
Contributor Author

@Cammisuli perfect! I think, I'd like to check a bit later whether the case must also be covered for npm/pnpm

…and stop passing `keyMap` as a func argument since it is declared in a global scope already
@newsiberian newsiberian force-pushed the graph-builder-npm-version-recognition branch from 5777536 to 69027a1 Compare February 22, 2025 11:49
@newsiberian
Copy link
Contributor Author

@Cammisuli it looks like npm, pnpm are not affected. so no additional changes from my side. Synced w/ master, though

@Cammisuli Cammisuli enabled auto-merge (squash) February 24, 2025 14:29
@Cammisuli Cammisuli merged commit 75a69d9 into nrwl:master Feb 24, 2025
12 checks passed
Copy link

github-actions bot commented Mar 2, 2025

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consistent "Failed to process project graph"
2 participants