From ad80e2b07231c6fd0d004ecdec55de76da748b6a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 16 Oct 2026 07:40:33 +0000 Subject: [PATCH] fix(@angular/build): align lazy route entry names with workspace root for SSR modulepreload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Override `compilerOptions.basePath` with `build.initialOptions.absWorkingDir` when initializing the Angular compilation so `lazyRoutesTransformer` computes `ɵentryName` relative to the workspace root rather than the tsconfig directory. This matches the workspace-relative keys in `entryPointToBrowserMapping` used for SSR `modulepreload` link generation when the application's `tsconfig` is not located at the workspace root. Closes #34369 --- .../behavior/chunk-optimization-server_spec.ts | 16 ++++++++++------ .../compilation/angular-compilation_spec.ts | 8 +++++++- .../angular/compilation/compiler-options.ts | 2 ++ .../src/tools/esbuild/angular/compiler-plugin.ts | 1 + 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts index 76ecbbc4329e..18b92e7690a0 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts @@ -151,15 +151,19 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .not.toBeNull(); const mapping = JSON.parse(mappingSource![1]) as Record; + const mainServerContent = harness.readFile('dist/server/main.server.mjs'); - // Every lazy route entry point must retain a mapping entry after optimization. + // Every lazy route entry point must retain a mapping entry after optimization + // that matches the ɵentryName emitted into the server bundle. for (const name of LAZY_ROUTE_NAMES) { - const key = Object.keys(mapping).find((entryPoint) => - entryPoint.endsWith(`${name}.component.ts`), - ); - expect(key) - .withContext(`mapping entry for lazy route '${name}' should exist`) + const expectedEntryPoint = `src/app/${name}.component.ts`; + expect(mapping[expectedEntryPoint]) + .withContext(`mapping entry for '${expectedEntryPoint}' should exist`) .toBeDefined(); + + expect(mainServerContent) + .withContext(`main.server.mjs should contain ɵentryName '${expectedEntryPoint}'`) + .toContain(expectedEntryPoint); } // Every browser file referenced by the mapping must exist on disk. diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 71eacd562259..0499431fe2c9 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -326,7 +326,11 @@ describe('AngularCompilation', () => { it('applies override options correctly', () => { const { compilerOptions } = transformCompilerOptions( ts, - { target: ts.ScriptTarget.ES2022, isolatedModules: true }, + { + target: ts.ScriptTarget.ES2022, + isolatedModules: true, + basePath: '/workspace/projects/app', + }, { sourcemap: true, preserveSymlinks: true, @@ -334,9 +338,11 @@ describe('AngularCompilation', () => { enableHmr: true, instrumentForCoverage: true, includeTestMetadata: true, + basePath: '/workspace', }, ); + expect(compilerOptions.basePath).toBe('/workspace'); expect(compilerOptions.inlineSources).toBe(true); expect(compilerOptions.inlineSourceMap).toBe(true); expect(compilerOptions.preserveSymlinks).toBe(true); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 45af80eae6d3..81ef9425b610 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -21,6 +21,7 @@ export interface CompilerOptionOverrides { includeTestMetadata?: boolean; customConditions?: string[]; rootFiles?: string[]; + basePath?: string; } export function transformCompilerOptions( @@ -113,6 +114,7 @@ export function transformCompilerOptions( return { compilerOptions: { ...compilerOptions, + basePath: overrides?.basePath ?? compilerOptions.basePath, noEmitOnError: false, composite: false, inlineSources: !!overrides?.sourcemap, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 9a36eea56d61..cd53d6085e65 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -331,6 +331,7 @@ export function createCompilerPlugin( includeTestMetadata: !!pluginOptions.includeTestMetadata, customConditions: build.initialOptions.conditions, rootFiles: pluginOptions.rootFiles, + basePath: build.initialOptions.absWorkingDir, }, );