fix(core): clean versions read from package.json when resolving depen… (#26457)

…dencies

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

## Current Behavior
<!-- This is the behavior we have today -->

When versions in published `package.json` files such as
https://unpkg.com/@trpc/server@11.0.0-rc.394/package.json are depended
on, the version is not cleaned of extra parts of the version, and the
dependency is resolved properly.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

When versions in published `package.json` files such as
https://unpkg.com/@trpc/server@11.0.0-rc.394/package.json are depended
on, the version is cleaned and resolves properly as a dependency.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes https://github.com/nrwl/nx/issues/26410
This commit is contained in:
Jason Jean 2024-06-07 13:55:57 -04:00 committed by GitHub
parent 6de382c8a2
commit 08a0e5cb59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 24 deletions

View File

@ -83,15 +83,15 @@ describe('TargetProjectLocator', () => {
'./tsconfig.base.json': JSON.stringify(tsConfig),
'./node_modules/@ng/core/package.json': JSON.stringify({
name: '@ng/core',
version: '1',
version: '1.0.0',
}),
'./node_modules/npm-package/package.json': JSON.stringify({
name: 'npm-package',
version: '1',
version: '1.0.0',
}),
'./node_modules/@proj/proj123-base/package.json': JSON.stringify({
name: '@proj/proj123-base',
version: '1',
version: '1.0.0',
}),
};
vol.fromJSON(fsJson, '/root');
@ -200,7 +200,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@ng/core',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@ng/core',
},
},
@ -208,7 +208,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@ng/common',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@ng/common',
},
},
@ -216,7 +216,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:npm-package',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: 'npm-package',
},
},
@ -224,7 +224,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/my-second-proj',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/my-second-proj',
},
},
@ -232,7 +232,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj5',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj5',
},
},
@ -240,7 +240,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj6',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj6',
},
},
@ -248,7 +248,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj7',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj7',
},
},
@ -256,7 +256,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj123-base',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj123-base',
},
},
@ -487,15 +487,19 @@ describe('TargetProjectLocator', () => {
'./libs/proj1234-child/index.ts': 'export const a = 12345',
'./node_modules/@proj/proj123-base/package.json': JSON.stringify({
name: '@proj/proj123-base',
version: '1',
version: '1.0.0',
}),
'./node_modules/@ng/core/package.json': JSON.stringify({
name: '@ng/core',
version: '1',
version: '1.0.0',
}),
'./node_modules/npm-package/package.json': JSON.stringify({
name: 'npm-package',
version: '1',
version: '1.0.0',
}),
'./node_modules/@trpc/server/package.json': JSON.stringify({
name: '@trpc/server',
version: '1.0.0-rc.0+abc123',
}),
// minimatch is a real world example of a multi module format package with nested package.json files.
// node will resolve the dist/cjs/package.json file when using require.resolve('minimatch') in commonjs
@ -595,7 +599,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@ng/core',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@ng/core',
},
},
@ -603,7 +607,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@ng/common',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@ng/common',
},
},
@ -611,7 +615,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:npm-package',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: 'npm-package',
},
},
@ -619,7 +623,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/my-second-proj',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/my-second-proj',
},
},
@ -627,7 +631,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj5',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj5',
},
},
@ -635,7 +639,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj6',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj6',
},
},
@ -643,7 +647,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj7',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj7',
},
},
@ -651,7 +655,7 @@ describe('TargetProjectLocator', () => {
name: 'npm:@proj/proj123-base',
type: 'npm',
data: {
version: '1',
version: '1.0.0',
packageName: '@proj/proj123-base',
},
},
@ -679,6 +683,15 @@ describe('TargetProjectLocator', () => {
hash: 'sha512-ggewenDQWc5azOEM/HI7AREuIHXSPO0STL+ehAG2PvoQPHglCdfLQy904D85ttm9wS7AKdK+d3wqMzSQaj7FsA==',
},
},
'npm:@trpc/server': {
type: 'npm',
name: 'npm:@trpc/server',
data: {
version: '1.0.0-rc.0',
packageName: '@trpc/server',
hash: 'sha512-ggewenDQWc5azOEM/HI7AREuIHXSPO0STL+ehAG2PvoQPHglCdfLQy904D85ttm9wS7AKdK+d3wqMzSQaj7FsA==',
},
},
/**
* We use minimatch as an example of a multiple module format package.
*/
@ -774,6 +787,14 @@ describe('TargetProjectLocator', () => {
expect(similarDeepImportFromNpm).toEqual('npm:@proj/proj123-base');
});
it('should be able to resolve npm projects with unclean versions', () => {
const trpcProject = targetProjectLocator.findProjectFromImport(
'@trpc/server',
'libs/proj/index.ts'
);
expect(trpcProject).toEqual('npm:@trpc/server');
});
it('should return null for native modules', () => {
const result = targetProjectLocator.findProjectFromImport(
'path',

View File

@ -1,6 +1,6 @@
import { existsSync } from 'node:fs';
import { builtinModules } from 'node:module';
import { dirname, join, parse, posix, relative } from 'node:path';
import { clean } from 'semver';
import {
ProjectGraphExternalNode,
ProjectGraphProjectNode,
@ -186,7 +186,8 @@ export class TargetProjectLocator {
return externalNodeName;
}
const npmProjectKey = `npm:${externalPackageJson.name}@${externalPackageJson.version}`;
const version = clean(externalPackageJson.version);
const npmProjectKey = `npm:${externalPackageJson.name}@${version}`;
const matchingExternalNode = this.npmProjects[npmProjectKey];
if (!matchingExternalNode) {
return null;