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:
Kristiyan Kostadinov
2019-05-07 22:57:55 -04:00
committed by Alex Rickabaugh
parent 2f35dbfd3b
commit f74373f2dd
18 changed files with 115 additions and 73 deletions

View File

@ -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);
}

View 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);
}