From 727066c77fec06cd8aeec77615afb9dbf4cd50b2 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 29 Sep 2023 11:32:08 +0000 Subject: [PATCH] fix(@angular-devkit/build-angular): clean up internal Angular state during rendering SSR This commit clean ups the compiled components state when the build is being executed in watch mode. This is required as otherwise during development `Component ID generation collision detected` are displayed on the server. Closes: #25924 --- .../tools/esbuild/application-code-bundle.ts | 18 +++++++++++++++--- .../server-rendering/main-bundle-exports.ts | 2 ++ .../src/utils/server-rendering/render-page.ts | 6 ++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts index f59cc498b983..328897986d53 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts @@ -134,7 +134,15 @@ export function createServerCodeBundleOptions( target: string[], sourceFileCache: SourceFileCache, ): BuildOptions { - const { jit, serverEntryPoint, workspaceRoot, ssrOptions } = options; + const { + jit, + serverEntryPoint, + workspaceRoot, + ssrOptions, + watch, + externalPackages, + prerenderOptions, + } = options; assert( serverEntryPoint, @@ -194,7 +202,7 @@ export function createServerCodeBundleOptions( }; buildOptions.plugins ??= []; - if (options.externalPackages) { + if (externalPackages) { buildOptions.packages = 'external'; } else { buildOptions.plugins.push(createRxjsEsmResolutionPlugin()); @@ -225,7 +233,11 @@ export function createServerCodeBundleOptions( `export { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';`, ]; - if (options.prerenderOptions?.discoverRoutes) { + if (watch) { + contents.push(`export { ɵresetCompiledComponents } from '@angular/core';`); + } + + if (prerenderOptions?.discoverRoutes) { // We do not import it directly so that node.js modules are resolved using the correct context. const routesExtractorCode = await readFile( join(__dirname, '../../utils/routes-extractor/extractor.js'), diff --git a/packages/angular_devkit/build_angular/src/utils/server-rendering/main-bundle-exports.ts b/packages/angular_devkit/build_angular/src/utils/server-rendering/main-bundle-exports.ts index 866e478d8bcf..b212182cd37c 100644 --- a/packages/angular_devkit/build_angular/src/utils/server-rendering/main-bundle-exports.ts +++ b/packages/angular_devkit/build_angular/src/utils/server-rendering/main-bundle-exports.ts @@ -25,4 +25,6 @@ export interface MainServerBundleExports { /** Method to extract routes from the router config. */ extractRoutes: typeof extractRoutes; + + ɵresetCompiledComponents?: () => void; } diff --git a/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts b/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts index 9f0085582ab7..20548499daa2 100644 --- a/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts +++ b/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts @@ -45,8 +45,14 @@ export async function renderPage({ ɵSERVER_CONTEXT, renderModule, renderApplication, + ɵresetCompiledComponents, } = await loadBundle('./main.server.mjs'); + // Need to clean up GENERATED_COMP_IDS map in `@angular/core`. + // Otherwise an incorrect component ID generation collision detected warning will be displayed in development. + // See: https://github.com/angular/angular-cli/issues/25924 + ɵresetCompiledComponents?.(); + const platformProviders: StaticProvider[] = [ { provide: ɵSERVER_CONTEXT,