From 6c6d43086f542003ecf355f512e197392c0ed728 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Thu, 10 Jan 2019 13:44:17 -0800 Subject: [PATCH] fix(ivy): make module registration by id idempotent (#28033) An @NgModule with an 'id' property has its type registered in a global map of modules by id. This happens during compilation of the module. In Ivy, modules are first compiled when the @NgModule decorator executes. In tests, they might be passed again through the TestBed's compiler, resulting in a second compilation and registration. Before this fix, this second registration would cause an error, as the id was previously registered. This commit makes the registration idempotent, so if the same module type is being registered for the same id then no error is thrown. Testing strategy: future commits change the way the TestBed compiles modules, causing tests to become sensitive to this bug if not fixed. PR Close #28033 --- packages/core/src/linker/ng_module_factory_loader.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/linker/ng_module_factory_loader.ts b/packages/core/src/linker/ng_module_factory_loader.ts index 13e57d8fd3..c4660f71f8 100644 --- a/packages/core/src/linker/ng_module_factory_loader.ts +++ b/packages/core/src/linker/ng_module_factory_loader.ts @@ -35,12 +35,12 @@ const modules = new Map|NgModuleType>(); */ export function registerModuleFactory(id: string, factory: NgModuleFactory) { const existing = modules.get(id) as NgModuleFactory; - assertNotExisting(id, existing && existing.moduleType); + assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType); modules.set(id, factory); } -function assertNotExisting(id: string, type: Type| null): void { - if (type) { +function assertSameOrNotExisting(id: string, type: Type| null, incoming: Type): void { + if (type && type !== incoming) { throw new Error( `Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`); } @@ -48,7 +48,7 @@ function assertNotExisting(id: string, type: Type| null): void { export function registerNgModuleType(id: string, ngModuleType: NgModuleType) { const existing = modules.get(id) as NgModuleType | null; - assertNotExisting(id, existing); + assertSameOrNotExisting(id, existing, ngModuleType); modules.set(id, ngModuleType); }