From f86065e7702837e290086dcfeed8b9273b362021 Mon Sep 17 00:00:00 2001 From: Nicholas Cunningham Date: Fri, 10 May 2024 12:24:16 -0600 Subject: [PATCH] fix(nextjs): Moving a library using @nx/workspace:move should update server path closes: #20821 --- .../move/lib/update-imports.spec.ts | 37 +++++++++++++++++++ .../src/generators/move/lib/update-imports.ts | 30 ++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/packages/workspace/src/generators/move/lib/update-imports.spec.ts b/packages/workspace/src/generators/move/lib/update-imports.spec.ts index 49139aa146ebe..cff2940ca9fd9 100644 --- a/packages/workspace/src/generators/move/lib/update-imports.spec.ts +++ b/packages/workspace/src/generators/move/lib/update-imports.spec.ts @@ -493,4 +493,41 @@ export MyExtendedClass extends MyClass {};` '@proj/my-source': ['my-destination/src/index.ts'], }); }); + + it("should update project ref in the root tsconfig file if it contains a secondary entry point for Next.js's server", async () => { + await libraryGenerator(tree, { + name: 'my-source', + projectNameAndRootFormat: 'as-provided', + }); + + tree.write('my-source/src/server.ts', ''); + + updateJson(tree, '/tsconfig.base.json', (json) => { + json.compilerOptions.paths['@proj/my-source/server'] = [ + 'my-source/src/server.ts', + ]; + return json; + }); + + const projectConfig = readProjectConfiguration(tree, 'my-source'); + updateImports( + tree, + await normalizeSchema( + tree, + { + ...schema, + updateImportPath: false, + }, + projectConfig + ), + + projectConfig + ); + + const tsConfig = readJson(tree, '/tsconfig.base.json'); + expect(tsConfig.compilerOptions.paths).toEqual({ + '@proj/my-source': ['my-destination/src/index.ts'], + '@proj/my-source/server': ['my-destination/src/server.ts'], + }); + }); }); diff --git a/packages/workspace/src/generators/move/lib/update-imports.ts b/packages/workspace/src/generators/move/lib/update-imports.ts index e5c3df0f3d9f0..f741d9073037c 100644 --- a/packages/workspace/src/generators/move/lib/update-imports.ts +++ b/packages/workspace/src/generators/move/lib/update-imports.ts @@ -47,6 +47,7 @@ export function updateImports( let tsConfig: any; let mainEntryPointImportPath: string; let secondaryEntryPointImportPaths: string[]; + let serverEntryPointImportPath: string; if (tree.exists(tsConfigPath)) { tsConfig = readJson(tree, tsConfigPath); const sourceRoot = @@ -68,6 +69,19 @@ export function updateImports( !x.startsWith(ensureTrailingSlash(sourceRoot)) ) ); + + // Next.js libs have a custom path for the server we need to update that as well + // example "paths": { @acme/lib/server : ['libs/lib/src/server.ts'] } + serverEntryPointImportPath = Object.keys( + tsConfig.compilerOptions?.paths ?? {} + ).find((path) => + tsConfig.compilerOptions.paths[path].some( + (x) => + x.startsWith(ensureTrailingSlash(sourceRoot)) && + x.includes('server') && + path.endsWith('server') + ) + ); } mainEntryPointImportPath ??= normalizePathSlashes( @@ -77,7 +91,7 @@ export function updateImports( ) ); - const projectRefs = [ + let projectRefs = [ { from: mainEntryPointImportPath, to: schema.importPath, @@ -94,6 +108,20 @@ export function updateImports( })), ]; + if ( + serverEntryPointImportPath && + schema.importPath && + serverEntryPointImportPath.startsWith(mainEntryPointImportPath) + ) { + projectRefs.push({ + from: serverEntryPointImportPath, + to: serverEntryPointImportPath.replace( + mainEntryPointImportPath, + schema.importPath + ), + }); + } + for (const projectRef of projectRefs) { if (schema.updateImportPath && projectRef.to) { const replaceProjectRef = new RegExp(projectRef.from, 'g');