From 412d5af92cc266eddb8c2bdd5aabdb98dd1ff809 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Mon, 15 Sep 2025 11:30:10 -0700 Subject: [PATCH] refactor(upgrade): downgradeModule uses zone-based change detection by default (#63814) To avoid the need for specifying `provideZoneChangeDetection` in any/all modules used with `downgradedModule`, this change adds the zone-based change detection providers by default. PR Close #63814 --- packages/core/src/platform/platform_ref.ts | 4 +++- packages/upgrade/static/src/downgrade_module.ts | 15 +++++++++++---- .../test/integration/downgrade_module_spec.ts | 16 ---------------- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/core/src/platform/platform_ref.ts b/packages/core/src/platform/platform_ref.ts index da9e1105fd0..54b43e1f198 100644 --- a/packages/core/src/platform/platform_ref.ts +++ b/packages/core/src/platform/platform_ref.ts @@ -14,7 +14,7 @@ import { } from '../change_detection/scheduling/ng_zone_scheduling'; import {ChangeDetectionScheduler} from '../change_detection/scheduling/zoneless_scheduling'; import {ChangeDetectionSchedulerImpl} from '../change_detection/scheduling/zoneless_scheduling_impl'; -import {Injectable, Injector} from '../di'; +import {Injectable, Injector, StaticProvider} from '../di'; import {errorHandlerEnvironmentInitializer} from '../error_handler'; import {RuntimeError, RuntimeErrorCode} from '../errors'; import {Type} from '../interface/type'; @@ -39,6 +39,7 @@ export class PlatformRef { private _modules: NgModuleRef[] = []; private _destroyListeners: Array<() => void> = []; private _destroyed: boolean = false; + private _additionalApplicationProviders?: StaticProvider[]; /** @internal */ constructor(private _injector: Injector) {} @@ -67,6 +68,7 @@ export class PlatformRef { ngZoneFactory, }), {provide: ChangeDetectionScheduler, useExisting: ChangeDetectionSchedulerImpl}, + ...(this._additionalApplicationProviders ?? []), errorHandlerEnvironmentInitializer, ]; const moduleRef = createNgModuleRefWithProviders( diff --git a/packages/upgrade/static/src/downgrade_module.ts b/packages/upgrade/static/src/downgrade_module.ts index e58eb7a1ba2..e3fd532a46e 100644 --- a/packages/upgrade/static/src/downgrade_module.ts +++ b/packages/upgrade/static/src/downgrade_module.ts @@ -13,6 +13,7 @@ import { PlatformRef, StaticProvider, Type, + ɵinternalProvideZoneChangeDetection as internalProvideZoneChangeDetection, } from '@angular/core'; import {platformBrowser} from '@angular/platform-browser'; @@ -382,12 +383,18 @@ export function downgradeModule( let bootstrapFn: (extraProviders: StaticProvider[]) => Promise>; if (ɵutil.isNgModuleType(moduleOrBootstrapFn)) { // NgModule class - bootstrapFn = (extraProviders: StaticProvider[]) => - platformBrowser(extraProviders).bootstrapModule(moduleOrBootstrapFn); + bootstrapFn = (extraProviders: StaticProvider[]) => { + const platform = platformBrowser(extraProviders); + (platform as any)._additionalApplicationProviders = internalProvideZoneChangeDetection({}); + return platform.bootstrapModule(moduleOrBootstrapFn); + }; } else if (!ɵutil.isFunction(moduleOrBootstrapFn)) { // NgModule factory - bootstrapFn = (extraProviders: StaticProvider[]) => - platformBrowser(extraProviders).bootstrapModuleFactory(moduleOrBootstrapFn); + bootstrapFn = (extraProviders: StaticProvider[]) => { + const platform = platformBrowser(extraProviders); + (platform as any)._additionalApplicationProviders = internalProvideZoneChangeDetection({}); + return platform.bootstrapModuleFactory(moduleOrBootstrapFn); + }; } else { // bootstrap function bootstrapFn = moduleOrBootstrapFn; diff --git a/packages/upgrade/static/test/integration/downgrade_module_spec.ts b/packages/upgrade/static/test/integration/downgrade_module_spec.ts index 4fc996711e9..ff823b7bbbf 100644 --- a/packages/upgrade/static/test/integration/downgrade_module_spec.ts +++ b/packages/upgrade/static/test/integration/downgrade_module_spec.ts @@ -28,7 +28,6 @@ import { OnChanges, OnDestroy, OnInit, - provideZoneChangeDetection, StaticProvider, Type, ViewRef, @@ -488,7 +487,6 @@ withEachNg1Version(() => { {provide: 'FOO', useValue: 'Mod-foo'}, {provide: 'BAR', useValue: 'Mod-bar'}, {provide: 'BAZ', useValue: 'Mod-baz'}, - provideZoneChangeDetection(), ], }) class Ng2Module { @@ -686,7 +684,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2AComponent, Ng2BComponent], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -756,7 +753,6 @@ withEachNg1Version(() => { useFactory: (i: angular.IInjectorService) => i.get('ng1Value'), deps: ['$injector'], }, - provideZoneChangeDetection(), ], }) class Ng2Module { @@ -807,7 +803,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -847,7 +842,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -892,7 +886,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -967,7 +960,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [TestComponent, WrapperComponent], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1018,7 +1010,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1073,7 +1064,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [TestComponent, WrapperComponent], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1167,7 +1157,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1310,7 +1299,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1362,7 +1350,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {} @@ -1432,7 +1419,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], - providers: [provideZoneChangeDetection()], imports: [BrowserModule], }) class Ng2Module { @@ -1493,7 +1479,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { constructor(injector: Injector) { @@ -1528,7 +1513,6 @@ withEachNg1Version(() => { @NgModule({ declarations: [Ng2Component], imports: [BrowserModule], - providers: [provideZoneChangeDetection()], }) class Ng2Module { ngDoBootstrap() {}