fix(ivy): align NgModule registration timing with ViewEngine (#30244)
Currently in Ivy `NgModule` registration happens when the class is declared, however this is inconsistent with ViewEngine and requires extra generated code. These changes remove the generated code for `registerModuleFactory`, pass the id through to the `ngModuleDef` and do the module registration inside `NgModuleFactory.create`. This PR resolves FW-1285. PR Close #30244
This commit is contained in:

committed by
Alex Rickabaugh

parent
2f35dbfd3b
commit
f74373f2dd
@ -6,11 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from '../interface/type';
|
||||
import {NgModuleFactory as R3NgModuleFactory, NgModuleType} from '../render3/ng_module_ref';
|
||||
import {stringify} from '../util/stringify';
|
||||
|
||||
import {NgModuleFactory} from './ng_module_factory';
|
||||
import {getRegisteredNgModuleType} from './ng_module_factory_registration';
|
||||
|
||||
|
||||
/**
|
||||
@ -24,48 +23,14 @@ export abstract class NgModuleFactoryLoader {
|
||||
abstract load(path: string): Promise<NgModuleFactory<any>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of module-id to the corresponding NgModule.
|
||||
* - In pre Ivy we track NgModuleFactory,
|
||||
* - In post Ivy we track the NgModuleType
|
||||
*/
|
||||
const modules = new Map<string, NgModuleFactory<any>|NgModuleType>();
|
||||
|
||||
/**
|
||||
* Registers a loaded module. Should only be called from generated NgModuleFactory code.
|
||||
* @publicApi
|
||||
*/
|
||||
export function registerModuleFactory(id: string, factory: NgModuleFactory<any>) {
|
||||
const existing = modules.get(id) as NgModuleFactory<any>;
|
||||
assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType);
|
||||
modules.set(id, factory);
|
||||
}
|
||||
|
||||
function assertSameOrNotExisting(id: string, type: Type<any>| null, incoming: Type<any>): void {
|
||||
if (type && type !== incoming) {
|
||||
throw new Error(
|
||||
`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerNgModuleType(id: string, ngModuleType: NgModuleType) {
|
||||
const existing = modules.get(id) as NgModuleType | null;
|
||||
assertSameOrNotExisting(id, existing, ngModuleType);
|
||||
modules.set(id, ngModuleType);
|
||||
}
|
||||
|
||||
export function clearModulesForTest(): void {
|
||||
modules.clear();
|
||||
}
|
||||
|
||||
export function getModuleFactory__PRE_R3__(id: string): NgModuleFactory<any> {
|
||||
const factory = modules.get(id) as NgModuleFactory<any>| null;
|
||||
const factory = getRegisteredNgModuleType(id) as NgModuleFactory<any>| null;
|
||||
if (!factory) throw noModuleError(id);
|
||||
return factory;
|
||||
}
|
||||
|
||||
export function getModuleFactory__POST_R3__(id: string): NgModuleFactory<any> {
|
||||
const type = modules.get(id) as NgModuleType | null;
|
||||
const type = getRegisteredNgModuleType(id) as NgModuleType | null;
|
||||
if (!type) throw noModuleError(id);
|
||||
return new R3NgModuleFactory(type);
|
||||
}
|
||||
|
52
packages/core/src/linker/ng_module_factory_registration.ts
Normal file
52
packages/core/src/linker/ng_module_factory_registration.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from '../interface/type';
|
||||
import {NgModuleType} from '../render3/ng_module_ref';
|
||||
import {stringify} from '../util/stringify';
|
||||
|
||||
import {NgModuleFactory} from './ng_module_factory';
|
||||
|
||||
|
||||
/**
|
||||
* Map of module-id to the corresponding NgModule.
|
||||
* - In pre Ivy we track NgModuleFactory,
|
||||
* - In post Ivy we track the NgModuleType
|
||||
*/
|
||||
const modules = new Map<string, NgModuleFactory<any>|NgModuleType>();
|
||||
|
||||
/**
|
||||
* Registers a loaded module. Should only be called from generated NgModuleFactory code.
|
||||
* @publicApi
|
||||
*/
|
||||
export function registerModuleFactory(id: string, factory: NgModuleFactory<any>) {
|
||||
const existing = modules.get(id) as NgModuleFactory<any>;
|
||||
assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType);
|
||||
modules.set(id, factory);
|
||||
}
|
||||
|
||||
function assertSameOrNotExisting(id: string, type: Type<any>| null, incoming: Type<any>): void {
|
||||
if (type && type !== incoming) {
|
||||
throw new Error(
|
||||
`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerNgModuleType(id: string, ngModuleType: NgModuleType) {
|
||||
const existing = modules.get(id) as NgModuleType | null;
|
||||
assertSameOrNotExisting(id, existing, ngModuleType);
|
||||
modules.set(id, ngModuleType);
|
||||
}
|
||||
|
||||
export function clearModulesForTest(): void {
|
||||
modules.clear();
|
||||
}
|
||||
|
||||
export function getRegisteredNgModuleType(id: string) {
|
||||
return modules.get(id);
|
||||
}
|
Reference in New Issue
Block a user