refactor(core): change module semantics

This contains major changes to the compiler, bootstrap of the platforms
and test environment initialization.

Main part of #10043
Closes #10164

BREAKING CHANGE:
- Semantics and name of `@AppModule` (now `@NgModule`) changed quite a bit.
  This is actually not breaking as `@AppModules` were not part of rc.4.
  We will have detailed docs on `@NgModule` separately.
- `coreLoadAndBootstrap` and `coreBootstrap` can't be used any more (without migration support).
  Use `bootstrapModule` / `bootstrapModuleFactory` instead.
- All Components listed in routes have to be part of the `declarations` of an NgModule.
  Either directly on the bootstrap module / lazy loaded module, or in an NgModule imported by them.
This commit is contained in:
Tobias Bosch
2016-07-18 03:50:31 -07:00
parent ca16fc29a6
commit 46b212706b
129 changed files with 3580 additions and 3366 deletions

View File

@ -8,15 +8,15 @@
import {LowerCasePipe, NgIf} from '@angular/common';
import {XHR} from '@angular/compiler';
import {APP_INITIALIZER, Component, Directive, ExceptionHandler, Inject, Input, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, coreLoadAndBootstrap, createPlatform, provide} from '@angular/core';
import {APP_INITIALIZER, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, bootstrapModule, createPlatformFactory, provide} from '@angular/core';
import {ApplicationRef, disposePlatform} from '@angular/core/src/application_ref';
import {Console} from '@angular/core/src/console';
import {ComponentRef} from '@angular/core/src/linker/component_factory';
import {Testability, TestabilityRegistry} from '@angular/core/src/testability/testability';
import {ComponentFixture} from '@angular/core/testing';
import {AsyncTestCompleter, Log, afterEach, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it} from '@angular/core/testing/testing_internal';
import {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
import {BROWSER_APP_COMPILER_PROVIDERS, bootstrap} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
import {bootstrap, browserDynamicPlatform} from '@angular/platform-browser-dynamic';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
import {expect} from '@angular/platform-browser/testing/matchers';
@ -223,16 +223,10 @@ export function main() {
it('should unregister change detectors when components are disposed',
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
var platform =
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
var app = ReflectiveInjector
.resolveAndCreate(
[BROWSER_APP_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS, testProviders],
platform.injector)
.get(ApplicationRef);
coreLoadAndBootstrap(HelloRootCmp, app.injector).then((ref) => {
bootstrap(HelloRootCmp, testProviders).then((ref) => {
const appRef = ref.injector.get(ApplicationRef);
ref.destroy();
expect(() => app.tick()).not.toThrow();
expect(() => appRef.tick()).not.toThrow();
async.done();
});
}));
@ -258,24 +252,29 @@ export function main() {
});
}));
it('should run platform initializers', inject([Log], (log: Log) => {
let p = createPlatform(ReflectiveInjector.resolveAndCreate([
BROWSER_PLATFORM_PROVIDERS,
it('should run platform initializers',
inject([Log, AsyncTestCompleter], (log: Log, async: AsyncTestCompleter) => {
let p = createPlatformFactory(browserDynamicPlatform, 'someName', [
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init1'), multi: true},
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init2'), multi: true}
]));
])();
@NgModule({
imports: [BrowserModule],
providers: [
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
]
})
class SomeModule {
}
expect(log.result()).toEqual('platform_init1; platform_init2');
log.clear();
var a = ReflectiveInjector.resolveAndCreate(
[
BROWSER_APP_PROVIDERS,
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
],
p.injector);
a.get(ApplicationRef);
expect(log.result()).toEqual('app_init1; app_init2');
bootstrapModule(SomeModule, p).then(() => {
expect(log.result()).toEqual('app_init1; app_init2');
async.done();
});
}));
it('should register each application with the testability registry',
@ -305,7 +304,7 @@ export function main() {
])).then((compRef) => {
expect(el).toHaveText('hello world!');
expect(compilerConsole.warnings).toEqual([
'Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.'
'Passing XHR as regular provider is deprecated. Pass the provider via "compilerOptions" instead.'
]);
async.done();
});
@ -325,10 +324,8 @@ export function main() {
.toBe('transformed someValue');
expect(compilerConsole.warnings).toEqual([
'Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.',
'Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.',
`Providing platform directives via the PLATFORM_DIRECTIVES provider or the "CompilerConfig" is deprecated. Provide platform directives via an @AppModule instead. Directives: ${stringify(SomeDirective)}`,
`Providing platform pipes via the PLATFORM_PIPES provider or the "CompilerConfig" is deprecated. Provide platform pipes via an @AppModule instead. Pipes: ${stringify(SomePipe)}`
`The PLATFORM_DIRECTIVES provider and CompilerConfig.platformDirectives is deprecated. Add the directives to an NgModule instead! (Directives: ${stringify(SomeDirective)})`,
`The PLATFORM_PIPES provider and CompilerConfig.platformPipes is deprecated. Add the pipes to an NgModule instead! (Pipes: ${stringify(SomePipe)})`
]);
async.done();
});

View File

@ -8,7 +8,7 @@
import {NgIf} from '@angular/common';
import {CompilerConfig, XHR} from '@angular/compiler';
import {AppModule, Component, ComponentFactoryResolver, Directive, Injectable, Input, Pipe, ViewMetadata, provide} from '@angular/core';
import {Component, ComponentFactoryResolver, Directive, Injectable, Input, NgModule, Pipe, ViewMetadata, provide} from '@angular/core';
import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncPrecompilation, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers';
@ -112,8 +112,8 @@ class SomePipe {
class CompUsingModuleDirectiveAndPipe {
}
@AppModule({})
class SomeNestedModule {
@NgModule()
class SomeLibModule {
}
@Component({
@ -233,10 +233,9 @@ export function main() {
beforeEach(() => {
moduleConfig = {
providers: [FancyService],
directives: [SomeDirective],
pipes: [SomePipe],
precompile: [CompUsingModuleDirectiveAndPipe],
modules: [SomeNestedModule]
imports: [SomeLibModule],
declarations: [SomeDirective, SomePipe, CompUsingModuleDirectiveAndPipe],
precompile: [CompUsingModuleDirectiveAndPipe]
};
});
@ -256,9 +255,9 @@ export function main() {
expect(el.children[0].properties['title']).toBe('transformed someValue');
}));
it('should use set up nested modules',
inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
it('should use set up library modules',
inject([SomeLibModule], (libModule: SomeLibModule) => {
expect(libModule).toBeAnInstanceOf(SomeLibModule);
}));
it('should use set up precompile components',
@ -284,11 +283,10 @@ export function main() {
expect(el.children[0].properties['title']).toBe('transformed someValue');
}));
it('should use set up nested modules',
withModule(() => moduleConfig)
.inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
}));
it('should use set up library modules',
withModule(() => moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => {
expect(libModule).toBeAnInstanceOf(SomeLibModule);
}));
it('should use set up precompile components',
withModule(() => moduleConfig)
@ -301,7 +299,7 @@ export function main() {
describe('precompile components with template url', () => {
beforeEach(async(() => {
configureModule({precompile: [CompWithUrlTemplate]});
configureModule({declarations: [CompWithUrlTemplate], precompile: [CompWithUrlTemplate]});
doAsyncPrecompilation();
}));
@ -450,7 +448,12 @@ export function main() {
expect(
() =>
it('should fail',
withModule(() => { return {precompile: [CompWithUrlTemplate]}; })
withModule(() => {
return {
declarations: [CompWithUrlTemplate],
precompile: [CompWithUrlTemplate]
};
})
.inject(
[ComponentFactoryResolver],
(resolver: ComponentFactoryResolver) => {

View File

@ -23,8 +23,8 @@ import {MessageBasedRenderer} from '@angular/platform-browser/src/web_workers/ui
import {createPairedMessageBuses, PairedMessageBuses} from '../shared/web_worker_test_util';
import {ServiceMessageBrokerFactory_} from '@angular/platform-browser/src/web_workers/shared/service_message_broker';
import {dispatchEvent} from '../../../../platform-browser/testing/browser_util';
import {BrowserTestModule} from '@angular/platform-browser/testing';
import {browserDynamicTestPlatform} from '@angular/platform-browser-dynamic/testing';
import {BrowserTestingModule} from '@angular/platform-browser/testing';
import {browserDynamicTestingPlatform} from '@angular/platform-browser-dynamic/testing';
export function main() {
function createWebWorkerBrokerFactory(
@ -65,8 +65,8 @@ export function main() {
beforeEach(() => {
uiRenderStore = new RenderStore();
var testUiInjector = new TestBed();
testUiInjector.platform = browserDynamicTestPlatform();
testUiInjector.appModule = BrowserTestModule;
testUiInjector.platform = browserDynamicTestingPlatform();
testUiInjector.ngModule = BrowserTestingModule;
testUiInjector.configureModule({
providers: [
Serializer, {provide: RenderStore, useValue: uiRenderStore},
@ -74,7 +74,7 @@ export function main() {
{provide: RootRenderer, useExisting: DomRootRenderer}
]
});
testUiInjector.initTestAppModule();
testUiInjector.initTestModule();
var uiSerializer = testUiInjector.get(Serializer);
var domRootRenderer = testUiInjector.get(DomRootRenderer);
workerRenderStore = new RenderStore();