From 21d65cb813e35f8450430ea3058d53467f77095d Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Mon, 23 Jan 2023 14:07:07 -0500 Subject: [PATCH] =?UTF-8?q?fix(core):=20use=20require.resolve=20instead=20?= =?UTF-8?q?of=20randomly=20matching=20from=20our=20=E2=80=A6=20(#14523)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/utils/target-project-locator.spec.ts | 11 ++++- .../nx/src/utils/target-project-locator.ts | 41 +++++++++---------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/packages/nx/src/utils/target-project-locator.spec.ts b/packages/nx/src/utils/target-project-locator.spec.ts index e8f22c66d5c46..9ba0f8630709f 100644 --- a/packages/nx/src/utils/target-project-locator.spec.ts +++ b/packages/nx/src/utils/target-project-locator.spec.ts @@ -781,16 +781,23 @@ describe('findTargetProjectWithImport (without tsconfig.json)', () => { }); it('should be able to resolve local project', () => { + jest + .spyOn(targetProjectLocator as any, 'resolveImportWithRequire') + .mockReturnValue('libs/proj1/index.ts'); + const result1 = targetProjectLocator.findProjectWithImport( '@org/proj1', 'libs/proj1/index.ts' ); + expect(result1).toEqual('@org/proj1'); + + jest + .spyOn(targetProjectLocator as any, 'resolveImportWithRequire') + .mockReturnValue('libs/proj1/some/nested/file.ts'); const result2 = targetProjectLocator.findProjectWithImport( '@org/proj1/some/nested/path', 'libs/proj1/index.ts' ); - - expect(result1).toEqual('@org/proj1'); expect(result2).toEqual('@org/proj1'); }); diff --git a/packages/nx/src/utils/target-project-locator.ts b/packages/nx/src/utils/target-project-locator.ts index b5d867195d615..22ca59b56fe86 100644 --- a/packages/nx/src/utils/target-project-locator.ts +++ b/packages/nx/src/utils/target-project-locator.ts @@ -17,7 +17,6 @@ export class TargetProjectLocator { private tsConfig = this.getRootTsConfig(); private paths = this.tsConfig.config?.compilerOptions?.paths; private typescriptResolutionCache = new Map(); - private projectResolutionCache = new Map(); private npmResolutionCache = new Map(); constructor( @@ -52,12 +51,6 @@ export class TargetProjectLocator { } } - // check if it exists in projects - const project = this.findProject(normalizedImportExpr); - if (project) { - return project; - } - // try to find npm package before using expensive typescript resolution const npmProject = this.findNpmPackage(normalizedImportExpr); if (npmProject) { @@ -77,6 +70,15 @@ export class TargetProjectLocator { } } + try { + const resolvedModule = this.resolveImportWithRequire( + normalizedImportExpr, + filePath + ); + + return this.findProjectOfResolvedModule(resolvedModule); + } catch {} + // nothing found, cache for later this.npmResolutionCache.set(normalizedImportExpr, undefined); return null; @@ -135,22 +137,17 @@ export class TargetProjectLocator { return; } - private findProject(importExpr: string): string | undefined { - if (this.projectResolutionCache.has(importExpr)) { - return this.projectResolutionCache.get(importExpr); - } else { - const project = Object.values(this.nodes).find( - (project) => - importExpr === project.name || - importExpr.startsWith(`${project.name}/`) - ); - if (project) { - this.projectResolutionCache.set(importExpr, project.name); - return project.name; - } - } + private resolveImportWithRequire( + normalizedImportExpr: string, + filePath: string + ) { + return posix.relative( + workspaceRoot, + require.resolve(normalizedImportExpr, { + paths: [dirname(filePath)], + }) + ); } - private findNpmPackage(npmImport: string): string | undefined { if (this.npmResolutionCache.has(npmImport)) { return this.npmResolutionCache.get(npmImport);