From 628d06c17c4b55b09131cfe34e59ddde3473aba8 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Thu, 18 Aug 2016 13:34:28 -0700 Subject: [PATCH] feat(core): Throw a descriptive error when BrowserModule is installed a second time (via lazy loading). (#10899) Such a configuration is unsupported and causes all kinds of problems. --- .../@angular/platform-browser/src/browser.ts | 8 +++++++- .../test/browser/bootstrap_spec.ts | 19 ++++++++++++++++++- .../platform-browser/index.d.ts | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/modules/@angular/platform-browser/src/browser.ts b/modules/@angular/platform-browser/src/browser.ts index d91a5718c2..339a958c3e 100644 --- a/modules/@angular/platform-browser/src/browser.ts +++ b/modules/@angular/platform-browser/src/browser.ts @@ -7,7 +7,7 @@ */ import {CommonModule, PlatformLocation} from '@angular/common'; -import {ApplicationModule, ExceptionHandler, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, SanitizationService, Testability, createPlatformFactory, platformCore} from '@angular/core'; +import {ApplicationModule, BaseException, ExceptionHandler, NgModule, Optional, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, SanitizationService, SkipSelf, Testability, createPlatformFactory, platformCore} from '@angular/core'; import {wtfInit} from '../core_private'; import {AnimationDriver} from '../src/dom/animation_driver'; @@ -93,4 +93,10 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver { exports: [CommonModule, ApplicationModule] }) export class BrowserModule { + constructor(@Optional() @SkipSelf() parentModule: BrowserModule) { + if (parentModule) { + throw new BaseException( + `BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.`); + } + } } diff --git a/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts b/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts index e7e9a81b66..7bdcdd8d0e 100644 --- a/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts +++ b/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts @@ -7,7 +7,7 @@ */ import {ResourceLoader} from '@angular/compiler'; -import {APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_INITIALIZER, Pipe, createPlatformFactory} from '@angular/core'; +import {APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_INITIALIZER, Pipe, createPlatformFactory} from '@angular/core'; import {ApplicationRef, destroyPlatform} from '@angular/core/src/application_ref'; import {Console} from '@angular/core/src/console'; import {ComponentRef} from '@angular/core/src/linker/component_factory'; @@ -216,6 +216,23 @@ export function main() { }); })); + it('should throw a descriptive error if BrowserModule is installed again via a lazily loaded module', + inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { + @NgModule({imports: [BrowserModule]}) + class AsyncModule { + } + bootstrap(HelloRootCmp, testProviders) + .then((ref: ComponentRef) => { + let compiler: Compiler = ref.injector.get(Compiler); + return compiler.compileModuleAsync(AsyncModule).then(factory => { + expect(() => factory.create(ref.injector)) + .toThrowError( + `BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.`); + }); + }) + .then(() => async.done(), err => async.fail(err)); + })); + it('should support multiple calls to bootstrap', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { var refPromise1 = bootstrap(HelloRootCmp, testProviders); diff --git a/tools/public_api_guard/platform-browser/index.d.ts b/tools/public_api_guard/platform-browser/index.d.ts index f655752690..3f486caadd 100644 --- a/tools/public_api_guard/platform-browser/index.d.ts +++ b/tools/public_api_guard/platform-browser/index.d.ts @@ -12,6 +12,7 @@ export declare const BROWSER_SANITIZATION_PROVIDERS: Array; /** @experimental */ export declare class BrowserModule { + constructor(parentModule: BrowserModule); } /** @stable */