refactor(core): clean up platform bootstrap and initTestEnvironment

- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
  on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
  * introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
  * introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).

BREAKING CHANGE:

## Migration from `setBaseTestProviders` to `initTestEnvironment`:

- For the browser platform:
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;

  setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
  ```

  AFTER:
  ```
  import {initTestEnvironment} from ‘@angular/core/testing’;
  import {browserDynamicTestPlatform,
      BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;

  initTestEnvironment(
      BrowserDynamicTestModule,
      browserDynamicTestPlatform());

  ```
- For the server platform:
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;

  setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS);
  ```

  AFTER:
  ```
  import {initTestEnvironment} from ‘@angular/core/testing’;
  import {serverTestPlatform,
      ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;

  initTestEnvironment(
      ServerTestModule,
      serverTestPlatform());

  ```

## Bootstrap changes
```
@AppModule({
  modules: [BrowserModule],
  precompile: [MainComponent],
  providers: […], // additional providers
  directives: […], // additional platform directives
  pipes: […] // additional platform pipes
})
class MyModule {
  constructor(appRef: ApplicationRef) {
    appRef.bootstrap(MainComponent);
  }
}

// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;

bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());

// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;

bootstrapModule(MyModule, browserDynamicPlatform());
```

Closes #9922
Part of #9726
This commit is contained in:
Tobias Bosch
2016-07-08 10:47:17 -07:00
parent d84a43c828
commit fa47890032
33 changed files with 470 additions and 316 deletions

View File

@ -7,9 +7,9 @@
*/
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
import {COMPILER_PROVIDERS, CompilerConfig, XHR} from '@angular/compiler';
import {AppModule, AppModuleRef, ApplicationRef, Compiler, ComponentRef, ComponentResolver, ExceptionHandler, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, coreLoadAndBootstrap, isDevMode} from '@angular/core';
import {BROWSER_APP_PROVIDERS, BrowserModule, WORKER_APP_APPLICATION_PROVIDERS, WORKER_SCRIPT, WORKER_UI_APPLICATION_PROVIDERS, bootstrapModuleFactory, browserPlatform, workerAppPlatform, workerUiPlatform} from '@angular/platform-browser';
import {COMPILER_PROVIDERS, CompilerConfig, XHR, RUNTIME_COMPILER_FACTORY,} from '@angular/compiler';
import {AppModule, AppModuleRef, ApplicationRef, Compiler, ComponentRef, ComponentResolver, ExceptionHandler, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, coreLoadAndBootstrap, bootstrapModule, bootstrapModuleFactory, isDevMode, OpaqueToken, PlatformRef, getPlatform, assertPlatform, createPlatform, PLATFORM_INITIALIZER, CompilerOptions, CompilerFactory, createPlatformFactory} from '@angular/core';
import {BROWSER_APP_PROVIDERS, BrowserModule, WORKER_APP_APPLICATION_PROVIDERS, WORKER_SCRIPT, WORKER_UI_APPLICATION_PROVIDERS, browserPlatform, workerAppPlatform, workerUiPlatform, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
import {Console, ReflectionCapabilities, reflector} from './core_private';
import {getDOM, initDomAdapter} from './platform_browser_private';
@ -18,8 +18,6 @@ import {ConcreteType, isPresent, stringify} from './src/facade/lang';
import {CachedXHR} from './src/xhr/xhr_cache';
import {XHRImpl} from './src/xhr/xhr_impl';
/**
* @experimental
*/
@ -36,61 +34,40 @@ export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
];
/**
* @experimental
*/
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
[{provide: XHR, useClass: CachedXHR}];
function _initGlobals() {
initDomAdapter();
function initReflector() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
}
/**
* Creates the runtime compiler for the browser.
* CompilerFactory for the browser dynamic platform
*
* @stable
* @experimental
*/
export function browserCompiler({useDebug, useJit = true, providers = []}: {
useDebug?: boolean,
useJit?: boolean,
providers?: Array<any /*Type | Provider | any[]*/>
} = {}): Compiler {
_initGlobals();
if (useDebug === undefined) {
useDebug = isDevMode();
}
const injector = ReflectiveInjector.resolveAndCreate([
COMPILER_PROVIDERS, {
provide: CompilerConfig,
useValue: new CompilerConfig({genDebugInfo: useDebug, useJit: useJit})
},
{provide: XHR, useClass: XHRImpl}, providers ? providers : []
]);
return injector.get(Compiler);
}
export const BROWSER_DYNAMIC_COMPILER_FACTORY =
RUNTIME_COMPILER_FACTORY.withDefaults({providers: [{provide: XHR, useClass: XHRImpl}]});
/**
* Creates an instance of an `@AppModule` for the browser platform.
* Providers for the browser dynamic platform
*
* ## Simple Example
*
* ```typescript
* @AppModule({
* modules: [BrowserModule]
* })
* class MyModule {}
*
* let moduleRef = bootstrapModule(MyModule);
* ```
* @stable
* @experimental
*/
export function bootstrapModule<M>(
moduleType: ConcreteType<M>, compiler: Compiler = browserCompiler()): Promise<AppModuleRef<M>> {
return compiler.compileAppModuleAsync(moduleType).then(bootstrapModuleFactory);
}
export const BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
BROWSER_PLATFORM_PROVIDERS,
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_COMPILER_FACTORY},
{provide: PLATFORM_INITIALIZER, useValue: initReflector, multi: true},
];
/**
* @experimental API related to bootstrapping are still under review.
*/
export const browserDynamicPlatform =
createPlatformFactory('browserDynamic', BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
/**
* Bootstrapping for Angular applications.
@ -175,13 +152,13 @@ export function bootstrap<C>(
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<C>>;
export function bootstrap<C>(
appComponentType: ConcreteType<C>,
{providers, directives, pipes, modules, precompile, compiler}?: {
{providers, directives, pipes, modules, precompile, compilerOptions}?: {
providers?: Array<any /*Type | Provider | any[]*/>,
directives?: any[],
pipes?: any[],
modules?: any[],
precompile?: any[],
compiler?: Compiler
compilerOptions?: CompilerOptions
}): Promise<ComponentRef<C>>;
export function bootstrap<C>(
appComponentType: ConcreteType<C>,
@ -191,10 +168,9 @@ export function bootstrap<C>(
pipes: any[],
modules: any[],
precompile: any[],
compiler: Compiler
compilerOptions: CompilerOptions
}): Promise<ComponentRef<C>> {
_initGlobals();
let compiler: Compiler;
let compilerOptions: CompilerOptions;
let compilerProviders: any = [];
let providers: any[] = [];
let directives: any[] = [];
@ -209,56 +185,8 @@ export function bootstrap<C>(
pipes = normalizeArray(customProvidersOrDynamicModule.pipes);
modules = normalizeArray(customProvidersOrDynamicModule.modules);
precompile = normalizeArray(customProvidersOrDynamicModule.precompile);
compiler = customProvidersOrDynamicModule.compiler;
compilerOptions = customProvidersOrDynamicModule.compilerOptions;
}
const deprecationMessages: string[] = [];
if (providers && providers.length > 0) {
// Note: This is a hack to still support the old way
// of configuring platform directives / pipes and the compiler xhr.
// This will soon be deprecated!
const inj = ReflectiveInjector.resolveAndCreate(providers);
const compilerConfig: CompilerConfig = inj.get(CompilerConfig, null);
if (compilerConfig) {
// Note: forms read the platform directives / pipes, modify them
// and provide a CompilerConfig out of it
directives = directives.concat(compilerConfig.platformDirectives);
pipes = pipes.concat(compilerConfig.platformPipes);
deprecationMessages.push(
`Passing a CompilerConfig to "bootstrap()" as provider is deprecated. Pass the provider to "createCompiler()" and call "bootstrap()" with the created compiler instead.`);
} else {
// If nobody provided a CompilerConfig, use the
// PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly.
const platformDirectives = inj.get(PLATFORM_DIRECTIVES, []);
if (platformDirectives.length > 0) {
deprecationMessages.push(
`Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.`);
}
directives = directives.concat(platformDirectives);
const platformPipes = inj.get(PLATFORM_PIPES, []);
if (platformPipes.length > 0) {
deprecationMessages.push(
`Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.`);
}
pipes = pipes.concat(platformPipes);
}
const xhr = inj.get(XHR, null);
if (xhr) {
compilerProviders.push([{provide: XHR, useValue: xhr}]);
deprecationMessages.push(
`Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider to "createCompiler()" and call "bootstrap()" with the created compiler instead.`);
}
// Need to copy console from providers to compiler
// as well so that we can test the above deprecation messages!
const console = inj.get(Console, null);
if (console) {
compilerProviders.push([{provide: Console, useValue: console}]);
}
}
if (!compiler) {
compiler = browserCompiler({providers: compilerProviders});
}
const console: Console = compiler.injector.get(Console);
deprecationMessages.forEach((msg) => { console.warn(msg); });
@AppModule({
providers: providers,
@ -268,13 +196,15 @@ export function bootstrap<C>(
precompile: precompile.concat([appComponentType])
})
class DynamicModule {
constructor(public appRef: ApplicationRef) {}
}
return bootstrapModule(DynamicModule, compiler)
.then(
(moduleRef) => moduleRef.instance.appRef.waitForAsyncInitializers().then(
() => moduleRef.instance.appRef.bootstrap(appComponentType)));
return bootstrapModule(
DynamicModule, browserDynamicPlatform(),
CompilerFactory.mergeOptions(compilerOptions, {deprecatedAppProviders: providers}))
.then((moduleRef) => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
return appRef.bootstrap(appComponentType);
});
}
/**
@ -296,7 +226,6 @@ export function bootstrapWorkerUi(
return PromiseWrapper.resolve(app.get(ApplicationRef));
}
/**
* @experimental
*/