From 1089261717ed44bf9ce72b05986084bfb00fc2e8 Mon Sep 17 00:00:00 2001 From: Vikram Subramanian Date: Tue, 10 Jul 2018 08:17:45 -0700 Subject: [PATCH] fix(core): mark NgModule as not the root if APP_ROOT is set to false (#24814) Tree shakable providers use the APP_ROOT token to determine where to attach themselves. APP_ROOT gets set on NgModule with BrowserModule irrespective of whether it is actually the root(Ex. in case of SSR app where the shell app is first bootstrapped without BrowserModule being the root module). This change allows a NgModule with BrowserModule to explicitly mark itself as not the root by setting APP_ROOT token to false. This allows tree shakable providers to be attached to the right rott module. PR Close #24814 --- packages/core/src/view/ng_module.ts | 2 +- packages/core/test/view/ng_module_spec.ts | 26 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/core/src/view/ng_module.ts b/packages/core/src/view/ng_module.ts index 15496ce80f..bd660bf817 100644 --- a/packages/core/src/view/ng_module.ts +++ b/packages/core/src/view/ng_module.ts @@ -43,7 +43,7 @@ export function moduleDef(providers: NgModuleProviderDef[]): NgModuleDefinition let isRoot: boolean = false; for (let i = 0; i < providers.length; i++) { const provider = providers[i]; - if (provider.token === APP_ROOT) { + if (provider.token === APP_ROOT && provider.value === true) { isRoot = true; } if (provider.flags & NodeFlags.TypeNgModule) { diff --git a/packages/core/test/view/ng_module_spec.ts b/packages/core/test/view/ng_module_spec.ts index 3d569c844b..34ce8fbeb9 100644 --- a/packages/core/test/view/ng_module_spec.ts +++ b/packages/core/test/view/ng_module_spec.ts @@ -14,6 +14,7 @@ import {NgModuleDefinition, NgModuleProviderDef, NodeFlags} from '@angular/core/ import {moduleDef, moduleProvideDef, resolveNgModuleDep} from '@angular/core/src/view/ng_module'; import {createNgModuleRef} from '@angular/core/src/view/refs'; import {tokenKey} from '@angular/core/src/view/util'; +import {APP_ROOT} from '../../src/di/scope'; class Foo {} @@ -229,4 +230,29 @@ describe('NgModuleRef_ injector', () => { ref.destroy(); expect(Service.destroyed).toBe(1); }); + + describe('moduleDef', () => { + function createProvider(token: any, value: any) { + return { + index: 0, + flags: NodeFlags.TypeValueProvider | NodeFlags.LazyProvider, + deps: [], token, value + }; + } + + it('sets isRoot to `true` when APP_ROOT is `true`', () => { + const def = moduleDef([createProvider(APP_ROOT, true)]); + expect(def.isRoot).toBe(true); + }); + + it('sets isRoot to `false` when APP_ROOT is absent', () => { + const def = moduleDef([]); + expect(def.isRoot).toBe(false); + }); + + it('sets isRoot to `false` when APP_ROOT is `false`', () => { + const def = moduleDef([createProvider(APP_ROOT, false)]); + expect(def.isRoot).toBe(false); + }); + }); });