From 9e0a7d85231fac0702806d970a37ffb039b7e6be Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 10 Dec 2024 14:42:35 +0000 Subject: [PATCH] refactor(core): add `DISABLE_COMPONENT_BOOTSTRAP` token Introduced the `DISABLE_COMPONENT_BOOTSTRAP` token to control the bootstrapping of components during application initialization. This token is utilized by the Angular CLI in the `@angular/ssr` package, particularly during server-side rendering (SSR) when extracting routes. When set to `true`, this token prevents the root component from being bootstrapped during SSR's route extraction phase, which is crucial for efficiently extracting routes without triggering component initialization. This mechanism separates the concerns of route extraction and component bootstrapping during SSR rendering, optimizing performance. If not provided or set to `false`, the default behavior of bootstrapping the root component(s) during initialization is maintained. --- packages/core/src/core_private_export.ts | 1 + packages/core/src/platform/bootstrap.ts | 36 +++++++++++++++++-- .../bundle.golden_symbols.json | 3 ++ .../animations/bundle.golden_symbols.json | 3 ++ .../cyclic_import/bundle.golden_symbols.json | 3 ++ .../bundling/defer/bundle.golden_symbols.json | 3 ++ .../forms_reactive/bundle.golden_symbols.json | 3 ++ .../bundle.golden_symbols.json | 3 ++ .../hello_world/bundle.golden_symbols.json | 3 ++ .../hydration/bundle.golden_symbols.json | 3 ++ .../router/bundle.golden_symbols.json | 3 ++ .../bundle.golden_symbols.json | 3 ++ .../bundling/todo/bundle.golden_symbols.json | 3 ++ 13 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/core/src/core_private_export.ts b/packages/core/src/core_private_export.ts index 9ef6d446bb7269..0734acee89d8b1 100644 --- a/packages/core/src/core_private_export.ts +++ b/packages/core/src/core_private_export.ts @@ -107,6 +107,7 @@ export { PendingTasksInternal as ɵPendingTasks, // TODO(atscott): remove once there is a release with PendingTasksInternal so adev can be updated PendingTasksInternal as ɵPendingTasksInternal, } from './pending_tasks'; +export {DISABLE_COMPONENT_BOOTSTRAP as ɵDISABLE_COMPONENT_BOOTSTRAP} from './platform/bootstrap'; export {ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS} from './platform/platform'; export {ReflectionCapabilities as ɵReflectionCapabilities} from './reflection/reflection_capabilities'; export {AnimationRendererType as ɵAnimationRendererType} from './render/api'; diff --git a/packages/core/src/platform/bootstrap.ts b/packages/core/src/platform/bootstrap.ts index c9d802754770d6..1041f596970d2e 100644 --- a/packages/core/src/platform/bootstrap.ts +++ b/packages/core/src/platform/bootstrap.ts @@ -8,7 +8,7 @@ import {Subscription} from 'rxjs'; import {PROVIDED_NG_ZONE} from '../change_detection/scheduling/ng_zone_scheduling'; -import {EnvironmentInjector, R3Injector} from '../di/r3_injector'; +import {R3Injector} from '../di/r3_injector'; import {ErrorHandler} from '../error_handler'; import {RuntimeError, RuntimeErrorCode} from '../errors'; import {DEFAULT_LOCALE_ID} from '../i18n/localization'; @@ -22,10 +22,29 @@ import {NgZone} from '../zone/ng_zone'; import {ApplicationInitStatus} from '../application/application_init'; import {_callAndReportToErrorHandler, ApplicationRef, remove} from '../application/application_ref'; import {PROVIDED_ZONELESS} from '../change_detection/scheduling/zoneless_scheduling'; -import {Injector} from '../di'; +import {InjectionToken, Injector} from '../di'; import {InternalNgModuleRef, NgModuleRef} from '../linker/ng_module_factory'; import {stringify} from '../util/stringify'; +/** + * InjectionToken used to disable the bootstrap of components. + * + * This token is used by the Angular CLI in the `@angular/ssr` package to control + * whether components should be bootstrapped during the application initialization process. + * Specifically, it is used during route extraction when server-side rendering is enabled. + * + * By setting this token to `true`, Angular prevents the root component from being bootstrapped + * and avoids invoking it during the route extraction phase, which is necessary for SSR + * to extract routes without requiring new APIs to be exposed. This mechanism helps separate + * the logic for route extraction and component bootstrapping during SSR rendering. + * + * When not provided or set to `false`, Angular will continue with the default behavior + * of bootstrapping the root component(s) during initialization. + */ +export const DISABLE_COMPONENT_BOOTSTRAP = new InjectionToken( + ngDevMode ? 'DISABLE_ROOT_COMPONENT_BOOTSTRAP' : '', +); + export interface BootstrapConfig { platformInjector: Injector; } @@ -125,6 +144,19 @@ export function bootstrap( // If the `LOCALE_ID` provider is defined at bootstrap then we set the value for ivy const localeId = envInjector.get(LOCALE_ID, DEFAULT_LOCALE_ID); setLocaleId(localeId || DEFAULT_LOCALE_ID); + + const disableComponentsBootstrap = envInjector.get(DISABLE_COMPONENT_BOOTSTRAP, false, { + optional: true, + }); + if (disableComponentsBootstrap) { + if (isApplicationBootstrapConfig(config)) { + return envInjector.get(ApplicationRef); + } + + config.allPlatformModules.push(config.moduleRef); + return config.moduleRef; + } + if (typeof ngDevMode === 'undefined' || ngDevMode) { const imagePerformanceService = envInjector.get(ImagePerformanceWarning); imagePerformanceService.start(); diff --git a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json index f64ab6e4d4f093..4cf96ddda37082 100644 --- a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json +++ b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json @@ -149,6 +149,9 @@ { "name": "DIMENSIONAL_PROP_SET" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/animations/bundle.golden_symbols.json b/packages/core/test/bundling/animations/bundle.golden_symbols.json index 9e1fee21f58492..686dc8077fa99b 100644 --- a/packages/core/test/bundling/animations/bundle.golden_symbols.json +++ b/packages/core/test/bundling/animations/bundle.golden_symbols.json @@ -173,6 +173,9 @@ { "name": "DIMENSIONAL_PROP_SET" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index bee79d36895a1c..f62a18b4ac3647 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -95,6 +95,9 @@ { "name": "DEFAULT_APP_ID" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/defer/bundle.golden_symbols.json b/packages/core/test/bundling/defer/bundle.golden_symbols.json index 8d0ad0bffdc276..55fa31e23454d7 100644 --- a/packages/core/test/bundling/defer/bundle.golden_symbols.json +++ b/packages/core/test/bundling/defer/bundle.golden_symbols.json @@ -128,6 +128,9 @@ { "name": "DEHYDRATED_VIEWS" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DI_DECORATOR_FLAG" }, diff --git a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json index 0f4181a8a92dc9..767c5cf5f165d7 100644 --- a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json @@ -140,6 +140,9 @@ { "name": "DEFAULT_VALUE_ACCESSOR" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json index 090ce6805ab244..da35ecbe32a4db 100644 --- a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json @@ -146,6 +146,9 @@ { "name": "DEFAULT_VALUE_ACCESSOR" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index e7957fed712e64..05a78f06352386 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -62,6 +62,9 @@ { "name": "ConsumerObserver" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT2" }, diff --git a/packages/core/test/bundling/hydration/bundle.golden_symbols.json b/packages/core/test/bundling/hydration/bundle.golden_symbols.json index a87abb1d3dd513..7ed7140af8a65e 100644 --- a/packages/core/test/bundling/hydration/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hydration/bundle.golden_symbols.json @@ -89,6 +89,9 @@ { "name": "DEFAULT_APP_ID" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/router/bundle.golden_symbols.json b/packages/core/test/bundling/router/bundle.golden_symbols.json index 726dd0c3db0812..72799f75510a3e 100644 --- a/packages/core/test/bundling/router/bundle.golden_symbols.json +++ b/packages/core/test/bundling/router/bundle.golden_symbols.json @@ -149,6 +149,9 @@ { "name": "DEFAULT_SERIALIZER" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json index d454dd92ce75a2..e90290ac0e6bea 100644 --- a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json +++ b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json @@ -80,6 +80,9 @@ { "name": "DEFAULT_APP_ID" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index dd37518a768668..eab7e89fed0332 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -95,6 +95,9 @@ { "name": "DEFAULT_APP_ID" }, + { + "name": "DISABLE_COMPONENT_BOOTSTRAP" + }, { "name": "DOCUMENT" },