From fa4789003240d8d0f442cef692985730824faa3b Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Fri, 8 Jul 2016 10:47:17 -0700 Subject: [PATCH] refactor(core): clean up platform bootstrap and initTestEnvironment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- modules/@angular/compiler-cli/README.md | 4 +- .../compiler-cli/integrationtest/test/util.ts | 4 +- modules/@angular/compiler/compiler.ts | 2 +- modules/@angular/compiler/src/compiler.ts | 111 +++++++++++++- modules/@angular/core/index.ts | 2 +- modules/@angular/core/src/application_ref.ts | 84 ++++++++++- modules/@angular/core/src/linker.ts | 2 +- modules/@angular/core/src/linker/compiler.ts | 62 ++++++++ .../@angular/core/testing/test_injector.ts | 29 ++-- .../platform-browser-dynamic/index.ts | 137 +++++------------- .../platform-browser-dynamic/testing.ts | 55 ++++--- modules/@angular/platform-browser/index.ts | 2 +- .../@angular/platform-browser/src/browser.ts | 50 +------ .../platform-browser/src/worker_app.ts | 28 ++-- .../platform-browser/src/worker_render.ts | 23 +-- .../test/browser/bootstrap_spec.ts | 2 +- .../worker/renderer_integration_spec.ts | 3 +- .../platform-browser/testing/browser.ts | 21 ++- modules/@angular/platform-server/index.ts | 2 +- .../@angular/platform-server/src/server.ts | 29 ++-- .../platform-server/testing/server.ts | 23 +-- modules/@angular/router/karma-test-shim.js | 5 +- scripts/ci-lite/offline_compiler_test.sh | 2 +- test-main.js | 5 +- tools/cjs-jasmine/test-cjs-main.ts | 3 +- tools/public_api_guard/core/index.d.ts | 25 ++++ tools/public_api_guard/core/testing.d.ts | 9 +- .../platform-browser-dynamic/index.d.ts | 17 +-- .../platform-browser-dynamic/testing.d.ts | 11 +- .../platform-browser/index.d.ts | 19 ++- .../platform-browser/testing.d.ts | 5 +- .../platform-server/index.d.ts | 5 +- .../platform-server/testing.d.ts | 5 +- 33 files changed, 470 insertions(+), 316 deletions(-) diff --git a/modules/@angular/compiler-cli/README.md b/modules/@angular/compiler-cli/README.md index 7969e2a679..60971dd4ed 100644 --- a/modules/@angular/compiler-cli/README.md +++ b/modules/@angular/compiler-cli/README.md @@ -49,8 +49,10 @@ bootstrap.ts ------------- import {MainModuleNgFactory} from './main_module.ngfactory'; +import {bootstrapModuleFactory} from '@angular/core'; +import {browserPlatform} from '@angular/platform-browser'; -MainModuleNgFactory.create(browserPlatform().injector); +bootstrapModuleFactory(MainModuleNgFactory, browserPlatform()); ``` ## Configuration diff --git a/modules/@angular/compiler-cli/integrationtest/test/util.ts b/modules/@angular/compiler-cli/integrationtest/test/util.ts index 9f2892888b..786dfe4cbb 100644 --- a/modules/@angular/compiler-cli/integrationtest/test/util.ts +++ b/modules/@angular/compiler-cli/integrationtest/test/util.ts @@ -6,14 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ -import {AppModuleFactory, AppModuleRef} from '@angular/core'; +import {AppModuleFactory, AppModuleRef, bootstrapModuleFactory} from '@angular/core'; import {ComponentFixture} from '@angular/core/testing'; import {serverPlatform} from '@angular/platform-server'; import {MainModuleNgFactory} from '../src/module.ngfactory'; export function createModule(factory: AppModuleFactory): AppModuleRef { - return factory.create(serverPlatform().injector); + return bootstrapModuleFactory(factory, serverPlatform()); } export function createComponent( diff --git a/modules/@angular/compiler/compiler.ts b/modules/@angular/compiler/compiler.ts index 4812b0f876..9d0826b891 100644 --- a/modules/@angular/compiler/compiler.ts +++ b/modules/@angular/compiler/compiler.ts @@ -11,7 +11,7 @@ * @description * Starting point to import all compiler APIs. */ -export {COMPILER_PROVIDERS, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileFactoryMetadata, CompileIdentifierMetadata, CompileMetadataWithIdentifier, CompileMetadataWithType, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, CompilerConfig, DEFAULT_PACKAGE_URL_PROVIDER, DirectiveResolver, OfflineCompiler, PipeResolver, RenderTypes, RuntimeCompiler, SourceModule, TEMPLATE_TRANSFORMS, UrlResolver, ViewResolver, XHR, createOfflineCompileUrlResolver} from './src/compiler'; +export {COMPILER_PROVIDERS, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileFactoryMetadata, CompileIdentifierMetadata, CompileMetadataWithIdentifier, CompileMetadataWithType, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, CompilerConfig, DEFAULT_PACKAGE_URL_PROVIDER, DirectiveResolver, OfflineCompiler, PipeResolver, RUNTIME_COMPILER_FACTORY, RenderTypes, RuntimeCompiler, SourceModule, TEMPLATE_TRANSFORMS, UrlResolver, ViewResolver, XHR, createOfflineCompileUrlResolver} from './src/compiler'; export {ElementSchemaRegistry} from './src/schema/element_schema_registry'; export * from './src/template_ast'; diff --git a/modules/@angular/compiler/src/compiler.ts b/modules/@angular/compiler/src/compiler.ts index f3229ad57a..bc1dd7b59f 100644 --- a/modules/@angular/compiler/src/compiler.ts +++ b/modules/@angular/compiler/src/compiler.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Compiler, ComponentResolver, Type} from '@angular/core'; +import {Compiler, CompilerFactory, CompilerOptions, ComponentResolver, Injectable, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, ViewEncapsulation, isDevMode} from '@angular/core'; export * from './template_ast'; export {TEMPLATE_TRANSFORMS} from './template_parser'; @@ -39,6 +39,7 @@ import {ViewResolver} from './view_resolver'; import {DirectiveResolver} from './directive_resolver'; import {PipeResolver} from './pipe_resolver'; import {Console, Reflector, reflector, ReflectorReader} from '../core_private'; +import {XHR} from './xhr'; /** * A set of providers that provide `RuntimeCompiler` and its dependencies to use for @@ -46,6 +47,8 @@ import {Console, Reflector, reflector, ReflectorReader} from '../core_private'; */ export const COMPILER_PROVIDERS: Array = /*@ts2dart_const*/[ + {provide: PLATFORM_DIRECTIVES, useValue: [], multi: true}, + {provide: PLATFORM_PIPES, useValue: [], multi: true}, {provide: Reflector, useValue: reflector}, {provide: ReflectorReader, useExisting: Reflector}, Console, @@ -70,3 +73,109 @@ export const COMPILER_PROVIDERS: Array = DirectiveResolver, PipeResolver ]; + +@Injectable() +export class _RuntimeCompilerFactory extends CompilerFactory { + createCompiler(options: CompilerOptions): Compiler { + const deprecationMessages: string[] = []; + let platformDirectivesFromAppProviders: any[] = []; + let platformPipesFromAppProviders: any[] = []; + let compilerProvidersFromAppProviders: any[] = []; + let useDebugFromAppProviders: boolean; + let useJitFromAppProviders: boolean; + let defaultEncapsulationFromAppProviders: ViewEncapsulation; + + if (options.deprecatedAppProviders && options.deprecatedAppProviders.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(options.deprecatedAppProviders); + const compilerConfig: CompilerConfig = inj.get(CompilerConfig, null); + if (compilerConfig) { + platformDirectivesFromAppProviders = compilerConfig.platformDirectives; + platformPipesFromAppProviders = compilerConfig.platformPipes; + useJitFromAppProviders = compilerConfig.useJit; + useDebugFromAppProviders = compilerConfig.genDebugInfo; + defaultEncapsulationFromAppProviders = compilerConfig.defaultEncapsulation; + deprecationMessages.push( + `Passing a CompilerConfig to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.`); + } else { + // If nobody provided a CompilerConfig, use the + // PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly if existing + platformDirectivesFromAppProviders = inj.get(PLATFORM_DIRECTIVES, []); + if (platformDirectivesFromAppProviders.length > 0) { + deprecationMessages.push( + `Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.`); + } + platformPipesFromAppProviders = inj.get(PLATFORM_PIPES, []); + if (platformPipesFromAppProviders.length > 0) { + deprecationMessages.push( + `Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.`); + } + } + const xhr = inj.get(XHR, null); + if (xhr) { + compilerProvidersFromAppProviders.push([{provide: XHR, useValue: xhr}]); + deprecationMessages.push( + `Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.`); + } + // Need to copy console from deprecatedAppProviders to compiler providers + // as well so that we can test the above deprecation messages in old style bootstrap + // where we only have app providers! + const console = inj.get(Console, null); + if (console) { + compilerProvidersFromAppProviders.push([{provide: Console, useValue: console}]); + } + } + + const injector = ReflectiveInjector.resolveAndCreate([ + COMPILER_PROVIDERS, { + provide: CompilerConfig, + useFactory: (platformDirectives: any[], platformPipes: any[]) => { + return new CompilerConfig({ + platformDirectives: + _mergeArrays(platformDirectivesFromAppProviders, platformDirectives), + platformPipes: _mergeArrays(platformPipesFromAppProviders, platformPipes), + // let explicit values from the compiler options overwrite options + // from the app providers. E.g. important for the testing platform. + genDebugInfo: _firstDefined(options.useDebug, useDebugFromAppProviders, isDevMode()), + // let explicit values from the compiler options overwrite options + // from the app providers + useJit: _firstDefined(options.useJit, useJitFromAppProviders, true), + // let explicit values from the compiler options overwrite options + // from the app providers + defaultEncapsulation: _firstDefined( + options.defaultEncapsulation, defaultEncapsulationFromAppProviders, + ViewEncapsulation.Emulated) + }); + }, + deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES] + }, + // options.providers will always contain a provider for XHR as well + // (added by platforms). So allow compilerProvidersFromAppProviders to overwrite this + _mergeArrays(options.providers, compilerProvidersFromAppProviders) + ]); + const console: Console = injector.get(Console); + deprecationMessages.forEach((msg) => { console.warn(msg); }); + + return injector.get(Compiler); + } +} + + +export const RUNTIME_COMPILER_FACTORY = new _RuntimeCompilerFactory(); + +function _firstDefined(...args: T[]): T { + for (var i = 0; i < args.length; i++) { + if (args[i] !== undefined) { + return args[i]; + } + } + return undefined; +} + +function _mergeArrays(...parts: any[][]): any[] { + let result: any[] = []; + parts.forEach((part) => result.push(...part)); + return result; +} diff --git a/modules/@angular/core/index.ts b/modules/@angular/core/index.ts index 6f3d8cb9d2..59013b965a 100644 --- a/modules/@angular/core/index.ts +++ b/modules/@angular/core/index.ts @@ -14,7 +14,7 @@ export * from './src/metadata'; export * from './src/util'; export * from './src/di'; -export {createPlatform, assertPlatform, disposePlatform, getPlatform, coreBootstrap, coreLoadAndBootstrap, PlatformRef, ApplicationRef, enableProdMode, lockRunMode, isDevMode} from './src/application_ref'; +export {createPlatform, assertPlatform, disposePlatform, getPlatform, bootstrapModuleFactory, bootstrapModule, coreBootstrap, coreLoadAndBootstrap, PlatformRef, ApplicationRef, enableProdMode, lockRunMode, isDevMode, createPlatformFactory} from './src/application_ref'; export {APP_ID, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER} from './src/application_tokens'; export * from './src/zone'; export * from './src/render'; diff --git a/modules/@angular/core/src/application_ref.ts b/modules/@angular/core/src/application_ref.ts index 1ddd1dd2c8..45c2a14b11 100644 --- a/modules/@angular/core/src/application_ref.ts +++ b/modules/@angular/core/src/application_ref.ts @@ -14,7 +14,9 @@ import {ConcreteType, IS_DART, Type, isBlank, isPresent, isPromise} from '../src import {APP_INITIALIZER, PLATFORM_INITIALIZER} from './application_tokens'; import {ChangeDetectorRef} from './change_detection/change_detector_ref'; import {Console} from './console'; -import {Inject, Injectable, Injector, Optional, OptionalMetadata, SkipSelf, SkipSelfMetadata, forwardRef} from './di'; +import {Inject, Injectable, Injector, OpaqueToken, Optional, OptionalMetadata, ReflectiveInjector, SkipSelf, SkipSelfMetadata, forwardRef} from './di'; +import {AppModuleFactory, AppModuleRef} from './linker/app_module_factory'; +import {Compiler, CompilerFactory, CompilerOptions} from './linker/compiler'; import {ComponentFactory, ComponentRef} from './linker/component_factory'; import {ComponentFactoryResolver} from './linker/component_factory_resolver'; import {ComponentResolver} from './linker/component_resolver'; @@ -111,6 +113,22 @@ export function createPlatform(injector: Injector): PlatformRef { return _platform; } +/** + * Creates a fatory for a platform + * + * @experimental APIs related to application bootstrap are currently under review. + */ +export function createPlatformFactory(name: string, providers: any[]): () => PlatformRef { + const marker = new OpaqueToken(`Platform: ${name}`); + return () => { + if (!getPlatform()) { + createPlatform( + ReflectiveInjector.resolveAndCreate(providers.concat({provide: marker, useValue: true}))); + } + return assertPlatform(marker); + }; +} + /** * Checks that there currently is a platform * which contains the given token as a provider. @@ -149,6 +167,70 @@ export function getPlatform(): PlatformRef { return isPresent(_platform) && !_platform.disposed ? _platform : null; } +/** + * Creates an instance of an `@AppModule` for the given platform + * for offline compilation. + * + * ## Simple Example + * + * ```typescript + * my_module.ts: + * + * @AppModule({ + * modules: [BrowserModule] + * }) + * class MyModule {} + * + * main.ts: + * import {MyModuleNgFactory} from './my_module.ngfactory'; + * import {bootstrapModuleFactory} from '@angular/core'; + * import {browserPlatform} from '@angular/platform-browser'; + * + * let moduleRef = bootstrapModuleFactory(MyModuleNgFactory, browserPlatform()); + * ``` + * + * @experimental APIs related to application bootstrap are currently under review. + */ +export function bootstrapModuleFactory( + moduleFactory: AppModuleFactory, platform: PlatformRef): AppModuleRef { + // Note: We need to create the NgZone _before_ we instantiate the module, + // as instantiating the module creates some providers eagerly. + // So we create a mini parent injector that just contains the new NgZone and + // pass that as parent to the AppModuleFactory. + const ngZone = new NgZone({enableLongStackTrace: isDevMode()}); + const ngZoneInjector = + ReflectiveInjector.resolveAndCreate([{provide: NgZone, useValue: ngZone}], platform.injector); + return ngZone.run(() => moduleFactory.create(ngZoneInjector)); +} + +/** + * Creates an instance of an `@AppModule` for a given platform using the given runtime compiler. + * + * ## Simple Example + * + * ```typescript + * @AppModule({ + * modules: [BrowserModule] + * }) + * class MyModule {} + * + * let moduleRef = bootstrapModule(MyModule, browserPlatform()); + * ``` + * @stable + */ +export function bootstrapModule( + moduleType: ConcreteType, platform: PlatformRef, + compilerOptions: CompilerOptions = {}): Promise> { + const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory); + const compiler = compilerFactory.createCompiler(compilerOptions); + return compiler.compileAppModuleAsync(moduleType) + .then((moduleFactory) => bootstrapModuleFactory(moduleFactory, platform)) + .then((moduleRef) => { + const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef); + return appRef.waitForAsyncInitializers().then(() => moduleRef); + }); +} + /** * Shortcut for ApplicationRef.bootstrap. * Requires a platform to be created first. diff --git a/modules/@angular/core/src/linker.ts b/modules/@angular/core/src/linker.ts index a290320b0a..0c9aedb00e 100644 --- a/modules/@angular/core/src/linker.ts +++ b/modules/@angular/core/src/linker.ts @@ -9,7 +9,7 @@ // Public API for compiler export {AppModuleFactory, AppModuleRef} from './linker/app_module_factory'; export {AppModuleFactoryLoader} from './linker/app_module_factory_loader'; -export {Compiler, ComponentStillLoadingError} from './linker/compiler'; +export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError} from './linker/compiler'; export {ComponentFactory, ComponentRef} from './linker/component_factory'; export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver'; export {ComponentResolver} from './linker/component_resolver'; diff --git a/modules/@angular/core/src/linker/compiler.ts b/modules/@angular/core/src/linker/compiler.ts index 4e3e4c7be0..8171011039 100644 --- a/modules/@angular/core/src/linker/compiler.ts +++ b/modules/@angular/core/src/linker/compiler.ts @@ -9,6 +9,7 @@ import {Injector} from '../di'; import {BaseException} from '../facade/exceptions'; import {ConcreteType, Type, stringify} from '../facade/lang'; +import {ViewEncapsulation} from '../metadata'; import {AppModuleMetadata} from '../metadata/app_module'; import {AppModuleFactory} from './app_module_factory'; @@ -86,3 +87,64 @@ export class Compiler { */ clearCacheFor(type: Type) {} } + +/** + * Options for creating a compiler + * + * @experimental + */ +export type CompilerOptions = { + useDebug?: boolean, + useJit?: boolean, + defaultEncapsulation?: ViewEncapsulation, + providers?: any[], + deprecatedAppProviders?: any[] +} + +/** + * A factory for creating a Compiler + * + * @experimental + */ +export abstract class CompilerFactory { + static mergeOptions(defaultOptions: CompilerOptions = {}, newOptions: CompilerOptions = {}): + CompilerOptions { + return { + useDebug: _firstDefined(newOptions.useDebug, defaultOptions.useDebug), + useJit: _firstDefined(newOptions.useJit, defaultOptions.useJit), + defaultEncapsulation: + _firstDefined(newOptions.defaultEncapsulation, defaultOptions.defaultEncapsulation), + providers: _mergeArrays(defaultOptions.providers, newOptions.providers), + deprecatedAppProviders: + _mergeArrays(defaultOptions.deprecatedAppProviders, newOptions.deprecatedAppProviders) + }; + } + + withDefaults(options: CompilerOptions = {}): CompilerFactory { + return new _DefaultApplyingCompilerFactory(this, options); + } + abstract createCompiler(options?: CompilerOptions): Compiler; +} + +class _DefaultApplyingCompilerFactory extends CompilerFactory { + constructor(private _delegate: CompilerFactory, private _options: CompilerOptions) { super(); } + + createCompiler(options: CompilerOptions = {}): Compiler { + return this._delegate.createCompiler(CompilerFactory.mergeOptions(this._options, options)); + } +} + +function _firstDefined(...args: T[]): T { + for (var i = 0; i < args.length; i++) { + if (args[i] !== undefined) { + return args[i]; + } + } + return undefined; +} + +function _mergeArrays(...parts: any[][]): any[] { + let result: any[] = []; + parts.forEach((part) => result.push(...part)); + return result; +} diff --git a/modules/@angular/core/testing/test_injector.ts b/modules/@angular/core/testing/test_injector.ts index e944c4b430..536a7fa77b 100644 --- a/modules/@angular/core/testing/test_injector.ts +++ b/modules/@angular/core/testing/test_injector.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AppModule, AppModuleFactory, AppModuleMetadata, AppModuleRef, Compiler, ComponentStillLoadingError, Injector, PlatformRef, Provider, Type} from '../index'; +import {AppModule, AppModuleFactory, AppModuleMetadata, AppModuleRef, Compiler, CompilerFactory, ComponentStillLoadingError, Injector, PlatformRef, Provider, Type} from '../index'; import {ListWrapper} from '../src/facade/collection'; import {BaseException} from '../src/facade/exceptions'; import {FunctionWrapper, isPresent, stringify} from '../src/facade/lang'; @@ -15,14 +15,6 @@ import {AsyncTestCompleter} from './async_test_completer'; const UNDEFINED = new Object(); -/** - * Signature of the compiler factory passed to `initTestEnvironment`. - * - * @experimental - */ -export type TestCompilerFactory = - (config: {providers?: Array, useJit?: boolean}) => Compiler; - /** * @experimental */ @@ -54,8 +46,6 @@ export class TestInjector implements Injector { this._instantiated = false; } - compilerFactory: TestCompilerFactory = null; - platform: PlatformRef = null; appModule: Type = null; @@ -118,8 +108,12 @@ export class TestInjector implements Injector { } private _createCompilerAndModuleMeta(): AppModuleMetadata { - this._compiler = - this.compilerFactory({providers: this._compilerProviders, useJit: this._compilerUseJit}); + const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory); + this._compiler = compilerFactory.createCompiler({ + providers: this._compilerProviders, + useJit: this._compilerUseJit, + deprecatedAppProviders: this._providers + }); const moduleMeta = new AppModuleMetadata({ providers: this._providers.concat([{provide: TestInjector, useValue: this}]), modules: this._modules.concat([this.appModule]), @@ -181,18 +175,16 @@ export function getTestInjector() { * suite on the current platform. If you absolutely need to change the providers, * first use `resetTestEnvironment`. * - * Test Providers for individual platforms are available from + * Test modules and platforms for individual platforms are available from * 'angular2/platform/testing/'. * * @experimental */ -export function initTestEnvironment( - compilerFactory: TestCompilerFactory, platform: PlatformRef, appModule: Type) { +export function initTestEnvironment(appModule: Type, platform: PlatformRef) { var testInjector = getTestInjector(); - if (testInjector.compilerFactory || testInjector.platform || testInjector.appModule) { + if (testInjector.platform || testInjector.appModule) { throw new BaseException('Cannot set base providers because it has already been called'); } - testInjector.compilerFactory = compilerFactory; testInjector.platform = platform; testInjector.appModule = appModule; } @@ -204,7 +196,6 @@ export function initTestEnvironment( */ export function resetTestEnvironment() { var testInjector = getTestInjector(); - testInjector.compilerFactory = null; testInjector.platform = null; testInjector.appModule = null; testInjector.reset(); diff --git a/modules/@angular/platform-browser-dynamic/index.ts b/modules/@angular/platform-browser-dynamic/index.ts index 782a524d99..c1626c6427 100644 --- a/modules/@angular/platform-browser-dynamic/index.ts +++ b/modules/@angular/platform-browser-dynamic/index.ts @@ -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 = [{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 -} = {}): 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( - moduleType: ConcreteType, compiler: Compiler = browserCompiler()): Promise> { - return compiler.compileAppModuleAsync(moduleType).then(bootstrapModuleFactory); -} +export const BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array = [ + 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( customProviders?: Array): Promise>; export function bootstrap( appComponentType: ConcreteType, - {providers, directives, pipes, modules, precompile, compiler}?: { + {providers, directives, pipes, modules, precompile, compilerOptions}?: { providers?: Array, directives?: any[], pipes?: any[], modules?: any[], precompile?: any[], - compiler?: Compiler + compilerOptions?: CompilerOptions }): Promise>; export function bootstrap( appComponentType: ConcreteType, @@ -191,10 +168,9 @@ export function bootstrap( pipes: any[], modules: any[], precompile: any[], - compiler: Compiler + compilerOptions: CompilerOptions }): Promise> { - _initGlobals(); - let compiler: Compiler; + let compilerOptions: CompilerOptions; let compilerProviders: any = []; let providers: any[] = []; let directives: any[] = []; @@ -209,56 +185,8 @@ export function bootstrap( 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( 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 */ diff --git a/modules/@angular/platform-browser-dynamic/testing.ts b/modules/@angular/platform-browser-dynamic/testing.ts index 4ce34daa79..b2679ab25c 100644 --- a/modules/@angular/platform-browser-dynamic/testing.ts +++ b/modules/@angular/platform-browser-dynamic/testing.ts @@ -8,47 +8,44 @@ import {CompilerConfig, DirectiveResolver, ViewResolver} from '@angular/compiler'; import {MockDirectiveResolver, MockViewResolver, OverridingTestComponentBuilder} from '@angular/compiler/testing'; -import {AppModule, Compiler, Provider, ReflectiveInjector, Type} from '@angular/core'; +import {AppModule, Compiler, CompilerFactory, PlatformRef, Provider, ReflectiveInjector, Type, createPlatformFactory} from '@angular/core'; import {TestComponentBuilder, TestComponentRenderer} from '@angular/core/testing'; -import {BrowserTestModule, browserTestPlatform} from '@angular/platform-browser/testing'; +import {BrowserTestModule, TEST_BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser/testing'; -import {BROWSER_APP_COMPILER_PROVIDERS} from './index'; +import {BROWSER_APP_COMPILER_PROVIDERS, BROWSER_DYNAMIC_COMPILER_FACTORY, BROWSER_DYNAMIC_PLATFORM_PROVIDERS} from './index'; import {DOMTestComponentRenderer} from './testing/dom_test_component_renderer'; export * from './private_export_testing' -const TEST_BROWSER_DYNAMIC_COMPILER_PROVIDERS: Array = [ - BROWSER_APP_COMPILER_PROVIDERS, - [ - { provide: DirectiveResolver, - useClass: MockDirectiveResolver }, - { provide: ViewResolver, - useClass: MockViewResolver } +/** + * CompilerFactory for browser dynamic test platform + * + * @experimental + */ +export const BROWSER_DYNAMIC_TEST_COMPILER_FACTORY = BROWSER_DYNAMIC_COMPILER_FACTORY.withDefaults({ + providers: [ + {provide: DirectiveResolver, useClass: MockDirectiveResolver}, + {provide: ViewResolver, useClass: MockViewResolver} ] +}); + + +/** + * Providers for the browser dynamic platform + * + * @experimental + */ +const BROWSER_DYNAMIC_TEST_PLATFORM_PROVIDERS: Array = [ + TEST_BROWSER_PLATFORM_PROVIDERS, + BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + {provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY}, ]; /** - * Creates a compiler for testing - * - * @stable - */ -export function browserTestCompiler( - {providers = [], useJit = true}: {providers?: Array, - useJit?: boolean} = {}): Compiler { - const injector = ReflectiveInjector.resolveAndCreate([ - TEST_BROWSER_DYNAMIC_COMPILER_PROVIDERS, - {provide: CompilerConfig, useValue: new CompilerConfig({genDebugInfo: true, useJit: useJit})}, - providers ? providers : [] - ]); - return injector.get(Compiler); -} - -/** - * Platform for testing. - * * @experimental API related to bootstrapping are still under review. */ -export const browserDynamicTestPlatform = browserTestPlatform; +export const browserDynamicTestPlatform = + createPlatformFactory('browserDynamicTest', BROWSER_DYNAMIC_TEST_PLATFORM_PROVIDERS); /** * AppModule for testing. diff --git a/modules/@angular/platform-browser/index.ts b/modules/@angular/platform-browser/index.ts index 8c1309f93f..7c54b8ef63 100644 --- a/modules/@angular/platform-browser/index.ts +++ b/modules/@angular/platform-browser/index.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -export {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, BrowserModule, bootstrapModuleFactory, browserPlatform} from './src/browser'; +export {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, BrowserModule, browserPlatform} from './src/browser'; export {BrowserPlatformLocation} from './src/browser/location/browser_platform_location'; export {Title} from './src/browser/title'; export {disableDebugTools, enableDebugTools} from './src/browser/tools/tools'; diff --git a/modules/@angular/platform-browser/src/browser.ts b/modules/@angular/platform-browser/src/browser.ts index 4c48cb4dce..343048a174 100644 --- a/modules/@angular/platform-browser/src/browser.ts +++ b/modules/@angular/platform-browser/src/browser.ts @@ -7,7 +7,7 @@ */ import {COMMON_DIRECTIVES, COMMON_PIPES, PlatformLocation} from '@angular/common'; -import {APPLICATION_COMMON_PROVIDERS, AppModule, AppModuleFactory, AppModuleRef, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, createPlatform, getPlatform, isDevMode} from '@angular/core'; +import {APPLICATION_COMMON_PROVIDERS, AppModule, AppModuleFactory, AppModuleRef, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode} from '@angular/core'; import {wtfInit} from '../core_private'; import {AnimationDriver} from '../src/dom/animation_driver'; @@ -28,7 +28,6 @@ import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host'; import {isBlank} from './facade/lang'; import {DomSanitizationService, DomSanitizationServiceImpl} from './security/dom_sanitization_service'; -const BROWSER_PLATFORM_MARKER = new OpaqueToken('BrowserPlatformMarker'); /** * A set of providers to initialize the Angular platform in a web browser. @@ -38,8 +37,7 @@ const BROWSER_PLATFORM_MARKER = new OpaqueToken('BrowserPlatformMarker'); * @experimental API related to bootstrapping are still under review. */ export const BROWSER_PLATFORM_PROVIDERS: Array = [ - {provide: BROWSER_PLATFORM_MARKER, useValue: true}, PLATFORM_COMMON_PROVIDERS, - {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true}, + PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true}, {provide: PlatformLocation, useClass: BrowserPlatformLocation} ]; @@ -80,12 +78,7 @@ export const BROWSER_APP_PROVIDERS: Array = [ /** * @experimental API related to bootstrapping are still under review. */ -export function browserPlatform(): PlatformRef { - if (isBlank(getPlatform())) { - createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS)); - } - return assertPlatform(BROWSER_PLATFORM_MARKER); -} +export const browserPlatform = createPlatformFactory('browser', BROWSER_PLATFORM_PROVIDERS); export function initDomAdapter() { BrowserDomAdapter.makeCurrent(); @@ -110,7 +103,8 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver { /** * The app module for the browser. - * @stable + * + * @experimental */ @AppModule({ providers: [ @@ -121,37 +115,3 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver { }) export class BrowserModule { } - -/** - * Creates an instance of an `@AppModule` for the browser platform - * for offline compilation. - * - * ## Simple Example - * - * ```typescript - * my_module.ts: - * - * @AppModule({ - * modules: [BrowserModule] - * }) - * class MyModule {} - * - * main.ts: - * import {MyModuleNgFactory} from './my_module.ngfactory'; - * import {bootstrapModuleFactory} from '@angular/platform-browser'; - * - * let moduleRef = bootstrapModuleFactory(MyModuleNgFactory); - * ``` - * @stable - */ -export function bootstrapModuleFactory(moduleFactory: AppModuleFactory): AppModuleRef { - let platformInjector = browserPlatform().injector; - // Note: We need to create the NgZone _before_ we instantiate the module, - // as instantiating the module creates some providers eagerly. - // So we create a mini parent injector that just contains the new NgZone and - // pass that as parent to the AppModuleFactory. - let ngZone = new NgZone({enableLongStackTrace: isDevMode()}); - let ngZoneInjector = - ReflectiveInjector.resolveAndCreate([{provide: NgZone, useValue: ngZone}], platformInjector); - return ngZone.run(() => { return moduleFactory.create(ngZoneInjector); }); -} diff --git a/modules/@angular/platform-browser/src/worker_app.ts b/modules/@angular/platform-browser/src/worker_app.ts index e89253b125..4f923625bf 100644 --- a/modules/@angular/platform-browser/src/worker_app.ts +++ b/modules/@angular/platform-browser/src/worker_app.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {FORM_PROVIDERS} from '@angular/common'; -import {APPLICATION_COMMON_PROVIDERS, APP_INITIALIZER, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PlatformRef, ReflectiveInjector, RootRenderer, assertPlatform, createPlatform, getPlatform} from '@angular/core'; +import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from '@angular/common'; +import {APPLICATION_COMMON_PROVIDERS, APP_INITIALIZER, AppModule, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PlatformRef, ReflectiveInjector, RootRenderer, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core'; import {BROWSER_SANITIZATION_PROVIDERS} from './browser'; import {isBlank, print} from './facade/lang'; @@ -28,13 +28,11 @@ class PrintLogger { logGroupEnd() {} } -const WORKER_APP_PLATFORM_MARKER = new OpaqueToken('WorkerAppPlatformMarker'); - /** * @experimental */ export const WORKER_APP_PLATFORM_PROVIDERS: Array = - [PLATFORM_COMMON_PROVIDERS, {provide: WORKER_APP_PLATFORM_MARKER, useValue: true}]; + PLATFORM_COMMON_PROVIDERS; /** * @experimental @@ -53,12 +51,7 @@ export const WORKER_APP_APPLICATION_PROVIDERS: Array = [ - PLATFORM_COMMON_PROVIDERS, {provide: WORKER_RENDER_PLATFORM_MARKER, useValue: true}, + PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initWebWorkerRenderPlatform, multi: true} ]; @@ -132,12 +131,7 @@ function initWebWorkerRenderPlatform(): void { /** * @experimental WebWorker support is currently experimental. */ -export function workerUiPlatform(): PlatformRef { - if (isBlank(getPlatform())) { - createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_UI_PLATFORM_PROVIDERS)); - } - return assertPlatform(WORKER_RENDER_PLATFORM_MARKER); -} +export const workerUiPlatform = createPlatformFactory('workerUi', WORKER_UI_PLATFORM_PROVIDERS); function _exceptionHandler(): ExceptionHandler { return new ExceptionHandler(getDOM()); @@ -181,3 +175,14 @@ function _resolveDefaultAnimationDriver(): AnimationDriver { // work with animations just yet... return AnimationDriver.NOOP; } + +/** + * The app module for the worker ui side. + * To use this, you need to create an own module that includes this module + * and provides the `WORKER_SCRIPT` token. + * + * @experimental + */ +@AppModule({providers: WORKER_UI_APPLICATION_PROVIDERS}) +export class WorkerUiModule { +} diff --git a/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts b/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts index 932f0e02b0..a65dc5d2da 100644 --- a/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts +++ b/modules/@angular/platform-browser/test/browser/bootstrap_spec.ts @@ -304,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 to "createCompiler()" and call "bootstrap()" with the created compiler instead.' + 'Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.' ]); async.done(); }); diff --git a/modules/@angular/platform-browser/test/web_workers/worker/renderer_integration_spec.ts b/modules/@angular/platform-browser/test/web_workers/worker/renderer_integration_spec.ts index 72b93f6fd3..bf404ea7f9 100644 --- a/modules/@angular/platform-browser/test/web_workers/worker/renderer_integration_spec.ts +++ b/modules/@angular/platform-browser/test/web_workers/worker/renderer_integration_spec.ts @@ -26,7 +26,7 @@ import {ServiceMessageBrokerFactory_} from '@angular/platform-browser/src/web_wo import {CompilerConfig} from '@angular/compiler'; import {dispatchEvent} from '../../../../platform-browser/testing/browser_util'; import {BrowserTestModule} from '@angular/platform-browser/testing'; -import {browserTestCompiler, browserDynamicTestPlatform} from '@angular/platform-browser-dynamic/testing' +import {browserDynamicTestPlatform} from '@angular/platform-browser-dynamic/testing' export function main() { function createWebWorkerBrokerFactory( @@ -70,7 +70,6 @@ export function main() { uiRenderStore = new RenderStore(); var testUiInjector = new TestInjector(); testUiInjector.platform = browserDynamicTestPlatform(); - testUiInjector.compilerFactory = browserTestCompiler; testUiInjector.appModule = BrowserTestModule; testUiInjector.configureModule({ providers: [ diff --git a/modules/@angular/platform-browser/testing/browser.ts b/modules/@angular/platform-browser/testing/browser.ts index ba3bc7b9e1..f31a408997 100644 --- a/modules/@angular/platform-browser/testing/browser.ts +++ b/modules/@angular/platform-browser/testing/browser.ts @@ -7,7 +7,7 @@ */ import {LocationStrategy} from '@angular/common'; -import {APP_ID, AppModule, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, getPlatform} from '@angular/core'; +import {APP_ID, AppModule, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core'; import {BROWSER_APP_PROVIDERS, BrowserModule} from '../src/browser'; import {BrowserDomAdapter} from '../src/browser/browser_adapter'; @@ -16,8 +16,6 @@ import {ELEMENT_PROBE_PROVIDERS} from '../src/dom/debug/ng_probe'; import {BrowserDetection} from './browser_util'; -const BROWSER_TEST_PLATFORM_MARKER = new OpaqueToken('BrowserTestPlatformMarker'); - function initBrowserTests() { BrowserDomAdapter.makeCurrent(); BrowserDetection.setup(); @@ -27,8 +25,13 @@ function createNgZone(): NgZone { return new NgZone({enableLongStackTrace: true}); } -const TEST_BROWSER_PLATFORM_PROVIDERS: Array = [ - PLATFORM_COMMON_PROVIDERS, {provide: BROWSER_TEST_PLATFORM_MARKER, useValue: true}, +/** + * Providers for the browser test platform + * + * @experimental + */ +export const TEST_BROWSER_PLATFORM_PROVIDERS: Array = [ + PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true} ]; @@ -37,12 +40,8 @@ const TEST_BROWSER_PLATFORM_PROVIDERS: Array = * * @experimental API related to bootstrapping are still under review. */ -export function browserTestPlatform(): PlatformRef { - if (!getPlatform()) { - createPlatform(ReflectiveInjector.resolveAndCreate(TEST_BROWSER_PLATFORM_PROVIDERS)); - } - return assertPlatform(BROWSER_TEST_PLATFORM_MARKER); -} +export const browserTestPlatform = + createPlatformFactory('browserTest', TEST_BROWSER_PLATFORM_PROVIDERS); /** * AppModule for testing. diff --git a/modules/@angular/platform-server/index.ts b/modules/@angular/platform-server/index.ts index 66e80c2578..f537b861de 100644 --- a/modules/@angular/platform-server/index.ts +++ b/modules/@angular/platform-server/index.ts @@ -6,4 +6,4 @@ * found in the LICENSE file at https://angular.io/license */ -export {SERVER_PLATFORM_PROVIDERS, serverBootstrap, serverPlatform} from './src/server'; +export {SERVER_PLATFORM_PROVIDERS, serverBootstrap, serverDynamicPlatform, serverPlatform} from './src/server'; diff --git a/modules/@angular/platform-server/src/server.ts b/modules/@angular/platform-server/src/server.ts index 33f2f59d9d..f1793a0582 100644 --- a/modules/@angular/platform-server/src/server.ts +++ b/modules/@angular/platform-server/src/server.ts @@ -7,14 +7,13 @@ */ import {PlatformLocation} from '@angular/common'; -import {ComponentRef, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, Type, assertPlatform, coreLoadAndBootstrap, createPlatform, getPlatform} from '@angular/core'; +import {CompilerFactory, ComponentRef, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, Type, assertPlatform, coreLoadAndBootstrap, createPlatform, createPlatformFactory, getPlatform} from '@angular/core'; +import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY} from '@angular/platform-browser-dynamic/testing'; import {ReflectionCapabilities, reflector, wtfInit} from '../core_private'; import {Parse5DomAdapter} from './parse5_adapter'; -const SERVER_PLATFORM_MARKER = new OpaqueToken('ServerPlatformMarker'); - function notSupported(feature: string): Error { throw new Error(`platform-server does not support '${feature}'.`); } @@ -39,9 +38,14 @@ class ServerPlatformLocation extends PlatformLocation { * @experimental */ export const SERVER_PLATFORM_PROVIDERS: Array = [ - {provide: SERVER_PLATFORM_MARKER, useValue: true}, PLATFORM_COMMON_PROVIDERS, + PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initParse5Adapter, multi: true}, - {provide: PlatformLocation, useClass: ServerPlatformLocation} + {provide: PlatformLocation, useClass: ServerPlatformLocation}, +]; + +const SERVER_DYNAMIC_PROVIDERS: any[] = [ + SERVER_PLATFORM_PROVIDERS, + {provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY}, ]; @@ -53,12 +57,15 @@ function initParse5Adapter() { /** * @experimental */ -export function serverPlatform(): PlatformRef { - if (!getPlatform()) { - createPlatform(ReflectiveInjector.resolveAndCreate(SERVER_PLATFORM_PROVIDERS)); - } - return assertPlatform(SERVER_PLATFORM_MARKER); -} +export const serverPlatform = createPlatformFactory('server', SERVER_PLATFORM_PROVIDERS); + +/** + * The server platform that supports the runtime compiler. + * + * @experimental + */ +export const serverDynamicPlatform = + createPlatformFactory('serverDynamic', SERVER_DYNAMIC_PROVIDERS); /** * Used to bootstrap Angular in server environment (such as node). diff --git a/modules/@angular/platform-server/testing/server.ts b/modules/@angular/platform-server/testing/server.ts index 022be046fc..fb3bc484ba 100644 --- a/modules/@angular/platform-server/testing/server.ts +++ b/modules/@angular/platform-server/testing/server.ts @@ -6,29 +6,20 @@ * found in the LICENSE file at https://angular.io/license */ -import {AppModule, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, getPlatform} from '@angular/core'; -import {BrowserDynamicTestModule, browserTestCompiler} from '@angular/platform-browser-dynamic/testing'; +import {AppModule, CompilerFactory, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core'; +import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY, BrowserDynamicTestModule} from '@angular/platform-browser-dynamic/testing'; import {Parse5DomAdapter} from '../src/parse5_adapter'; -const SERVER_TEST_PLATFORM_MARKER = new OpaqueToken('ServerTestPlatformMarker'); - function initServerTests() { Parse5DomAdapter.makeCurrent(); } -/** - * Creates a compiler for testing - * - * @stable - */ -export const serverTestCompiler = browserTestCompiler; - const TEST_SERVER_PLATFORM_PROVIDERS: Array = /*@ts2dart_const*/[ PLATFORM_COMMON_PROVIDERS, /*@ts2dart_Provider*/ {provide: PLATFORM_INITIALIZER, useValue: initServerTests, multi: true}, - {provide: SERVER_TEST_PLATFORM_MARKER, useValue: true} + {provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY}, ]; /** @@ -36,12 +27,8 @@ const TEST_SERVER_PLATFORM_PROVIDERS: Array = * * @experimental API related to bootstrapping are still under review. */ -export function serverTestPlatform(): PlatformRef { - if (!getPlatform()) { - createPlatform(ReflectiveInjector.resolveAndCreate(TEST_SERVER_PLATFORM_PROVIDERS)); - } - return assertPlatform(SERVER_TEST_PLATFORM_MARKER); -} +export const serverTestPlatform = + createPlatformFactory('serverTest', TEST_SERVER_PLATFORM_PROVIDERS); /** * AppModule for testing. diff --git a/modules/@angular/router/karma-test-shim.js b/modules/@angular/router/karma-test-shim.js index 6768c2e80c..222a4d192a 100644 --- a/modules/@angular/router/karma-test-shim.js +++ b/modules/@angular/router/karma-test-shim.js @@ -73,9 +73,8 @@ Promise.all([ var testingBrowser = providers[1]; testing.initTestEnvironment( - testingBrowser.browserTestCompiler, - testingBrowser.browserDynamicTestPlatform(), - testingBrowser.BrowserDynamicTestModule); + testingBrowser.BrowserDynamicTestModule, + testingBrowser.browserDynamicTestPlatform()); }).then(function() { // Finally, load all spec files. diff --git a/scripts/ci-lite/offline_compiler_test.sh b/scripts/ci-lite/offline_compiler_test.sh index 9d13b06f86..5027d1e103 100755 --- a/scripts/ci-lite/offline_compiler_test.sh +++ b/scripts/ci-lite/offline_compiler_test.sh @@ -3,7 +3,7 @@ set -ex -o pipefail # These ones can be `npm link`ed for fast development LINKABLE_PKGS=( - $(pwd)/dist/packages-dist/{common,core,compiler,compiler-cli,platform-{browser,server}} + $(pwd)/dist/packages-dist/{common,core,compiler,compiler-cli,platform-{browser,server},platform-browser-dynamic} $(pwd)/dist/tools/@angular/tsc-wrapped ) PKGS=( diff --git a/test-main.js b/test-main.js index a00efba040..e77fb7dd23 100644 --- a/test-main.js +++ b/test-main.js @@ -76,9 +76,8 @@ System.import('@angular/core/testing') return System.import('@angular/platform-browser-dynamic/testing') .then(function(browserTesting) { coreTesting.initTestEnvironment( - browserTesting.browserTestCompiler, - browserTesting.browserDynamicTestPlatform(), - browserTesting.BrowserDynamicTestModule); + browserTesting.BrowserDynamicTestModule, + browserTesting.browserDynamicTestPlatform()); }); }) .then(function() { diff --git a/tools/cjs-jasmine/test-cjs-main.ts b/tools/cjs-jasmine/test-cjs-main.ts index 9b223fe62a..af511998ef 100644 --- a/tools/cjs-jasmine/test-cjs-main.ts +++ b/tools/cjs-jasmine/test-cjs-main.ts @@ -2,5 +2,4 @@ var testingPlatformServer = require('../../all/@angular/platform-server/testing/ var testing = require('../../all/@angular/core/testing'); testing.initTestEnvironment( - testingPlatformServer.serverTestCompiler, testingPlatformServer.serverTestPlatform(), - testingPlatformServer.ServerTestModule); + testingPlatformServer.ServerTestModule, testingPlatformServer.serverTestPlatform()); diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index 07465bc6b6..7d25839ebb 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -256,6 +256,12 @@ export declare class Binding extends Provider { }); } +/** @stable */ +export declare function bootstrapModule(moduleType: ConcreteType, platform: PlatformRef, compilerOptions?: CompilerOptions): Promise>; + +/** @experimental */ +export declare function bootstrapModuleFactory(moduleFactory: AppModuleFactory, platform: PlatformRef): AppModuleRef; + /** @stable */ export declare enum ChangeDetectionStrategy { OnPush = 0, @@ -302,6 +308,22 @@ export declare class Compiler { compileComponentSync(component: ConcreteType): ComponentFactory; } +/** @experimental */ +export declare abstract class CompilerFactory { + abstract createCompiler(options?: CompilerOptions): Compiler; + withDefaults(options?: CompilerOptions): CompilerFactory; + static mergeOptions(defaultOptions?: CompilerOptions, newOptions?: CompilerOptions): CompilerOptions; +} + +/** @experimental */ +export declare type CompilerOptions = { + useDebug?: boolean; + useJit?: boolean; + defaultEncapsulation?: ViewEncapsulation; + providers?: any[]; + deprecatedAppProviders?: any[]; +}; + /** @stable */ export declare var Component: ComponentMetadataFactory; @@ -513,6 +535,9 @@ export declare function coreLoadAndBootstrap(componentType: Type, injector: Inje /** @experimental */ export declare function createPlatform(injector: Injector): PlatformRef; +/** @experimental */ +export declare function createPlatformFactory(name: string, providers: any[]): () => PlatformRef; + /** @stable */ export declare class CyclicDependencyError extends AbstractProviderError { constructor(injector: ReflectiveInjector, key: ReflectiveKey); diff --git a/tools/public_api_guard/core/testing.d.ts b/tools/public_api_guard/core/testing.d.ts index 555374fff1..d90f30c21c 100644 --- a/tools/public_api_guard/core/testing.d.ts +++ b/tools/public_api_guard/core/testing.d.ts @@ -83,7 +83,7 @@ export declare function getTestInjector(): TestInjector; export declare var iit: any; /** @experimental */ -export declare function initTestEnvironment(compilerFactory: TestCompilerFactory, platform: PlatformRef, appModule: Type): void; +export declare function initTestEnvironment(appModule: Type, platform: PlatformRef): void; /** @stable */ export declare function inject(tokens: any[], fn: Function): () => any; @@ -106,12 +106,6 @@ export declare var it: any; /** @experimental */ export declare function resetTestEnvironment(): void; -/** @experimental */ -export declare type TestCompilerFactory = (config: { - providers?: Array; - useJit?: boolean; -}) => Compiler; - /** @stable */ export declare class TestComponentBuilder { protected _injector: Injector; @@ -136,7 +130,6 @@ export declare class TestComponentRenderer { /** @experimental */ export declare class TestInjector implements Injector { appModule: Type; - compilerFactory: TestCompilerFactory; platform: PlatformRef; configureCompiler(config: { providers?: any[]; diff --git a/tools/public_api_guard/platform-browser-dynamic/index.d.ts b/tools/public_api_guard/platform-browser-dynamic/index.d.ts index ddb333534e..def0cbedbe 100644 --- a/tools/public_api_guard/platform-browser-dynamic/index.d.ts +++ b/tools/public_api_guard/platform-browser-dynamic/index.d.ts @@ -1,9 +1,6 @@ /** @experimental */ export declare function bootstrap(appComponentType: ConcreteType, customProviders?: Array): Promise>; -/** @stable */ -export declare function bootstrapModule(moduleType: ConcreteType, compiler?: Compiler): Promise>; - /** @experimental */ export declare function bootstrapWorkerApp(appComponentType: Type, customProviders?: Array): Promise>; @@ -13,12 +10,14 @@ export declare function bootstrapWorkerUi(workerScriptUri: string, customProvide /** @experimental */ export declare const BROWSER_APP_COMPILER_PROVIDERS: Array; -/** @stable */ -export declare function browserCompiler({useDebug, useJit, providers}?: { - useDebug?: boolean; - useJit?: boolean; - providers?: Array; -}): Compiler; +/** @experimental */ +export declare const BROWSER_DYNAMIC_COMPILER_FACTORY: CompilerFactory; + +/** @experimental */ +export declare const BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array; + +/** @experimental */ +export declare const browserDynamicPlatform: () => PlatformRef; /** @experimental */ export declare const CACHED_TEMPLATE_PROVIDER: Array; diff --git a/tools/public_api_guard/platform-browser-dynamic/testing.d.ts b/tools/public_api_guard/platform-browser-dynamic/testing.d.ts index f83d623436..faf1d8789d 100644 --- a/tools/public_api_guard/platform-browser-dynamic/testing.d.ts +++ b/tools/public_api_guard/platform-browser-dynamic/testing.d.ts @@ -1,12 +1,9 @@ +/** @experimental */ +export declare const BROWSER_DYNAMIC_TEST_COMPILER_FACTORY: CompilerFactory; + /** @stable */ export declare class BrowserDynamicTestModule { } /** @experimental */ -export declare const browserDynamicTestPlatform: typeof browserTestPlatform; - -/** @stable */ -export declare function browserTestCompiler({providers, useJit}?: { - providers?: Array; - useJit?: boolean; -}): Compiler; +export declare const browserDynamicTestPlatform: () => PlatformRef; diff --git a/tools/public_api_guard/platform-browser/index.d.ts b/tools/public_api_guard/platform-browser/index.d.ts index c1a7d2e281..3383391bfd 100644 --- a/tools/public_api_guard/platform-browser/index.d.ts +++ b/tools/public_api_guard/platform-browser/index.d.ts @@ -4,9 +4,6 @@ export declare abstract class AnimationDriver { static NOOP: AnimationDriver; } -/** @stable */ -export declare function bootstrapModuleFactory(moduleFactory: AppModuleFactory): AppModuleRef; - /** @experimental */ export declare const BROWSER_APP_PROVIDERS: Array; @@ -16,12 +13,12 @@ export declare const BROWSER_PLATFORM_PROVIDERS: Array; /** @experimental */ export declare const BROWSER_SANITIZATION_PROVIDERS: Array; -/** @stable */ +/** @experimental */ export declare class BrowserModule { } /** @experimental */ -export declare function browserPlatform(): PlatformRef; +export declare const browserPlatform: () => PlatformRef; /** @stable */ export declare class BrowserPlatformLocation extends PlatformLocation { @@ -227,7 +224,15 @@ export declare const WORKER_UI_PLATFORM_PROVIDERS: Array; export declare const WORKER_UI_STARTABLE_MESSAGING_SERVICE: OpaqueToken; /** @experimental */ -export declare function workerAppPlatform(): PlatformRef; +export declare class WorkerAppModule { +} /** @experimental */ -export declare function workerUiPlatform(): PlatformRef; +export declare const workerAppPlatform: () => PlatformRef; + +/** @experimental */ +export declare class WorkerUiModule { +} + +/** @experimental */ +export declare const workerUiPlatform: () => PlatformRef; diff --git a/tools/public_api_guard/platform-browser/testing.d.ts b/tools/public_api_guard/platform-browser/testing.d.ts index 19248cb7c7..e4c138834a 100644 --- a/tools/public_api_guard/platform-browser/testing.d.ts +++ b/tools/public_api_guard/platform-browser/testing.d.ts @@ -3,4 +3,7 @@ export declare class BrowserTestModule { } /** @experimental */ -export declare function browserTestPlatform(): PlatformRef; +export declare const browserTestPlatform: () => PlatformRef; + +/** @experimental */ +export declare const TEST_BROWSER_PLATFORM_PROVIDERS: Array; diff --git a/tools/public_api_guard/platform-server/index.d.ts b/tools/public_api_guard/platform-server/index.d.ts index 2d25e646e6..89a2abc719 100644 --- a/tools/public_api_guard/platform-server/index.d.ts +++ b/tools/public_api_guard/platform-server/index.d.ts @@ -5,4 +5,7 @@ export declare const SERVER_PLATFORM_PROVIDERS: Array; export declare function serverBootstrap(appComponentType: Type, providers: Array): Promise>; /** @experimental */ -export declare function serverPlatform(): PlatformRef; +export declare const serverDynamicPlatform: () => PlatformRef; + +/** @experimental */ +export declare const serverPlatform: () => PlatformRef; diff --git a/tools/public_api_guard/platform-server/testing.d.ts b/tools/public_api_guard/platform-server/testing.d.ts index d3dd91345a..68e6bb3e8f 100644 --- a/tools/public_api_guard/platform-server/testing.d.ts +++ b/tools/public_api_guard/platform-server/testing.d.ts @@ -1,9 +1,6 @@ -/** @stable */ -export declare const serverTestCompiler: typeof browserTestCompiler; - /** @stable */ export declare class ServerTestModule { } /** @experimental */ -export declare function serverTestPlatform(): PlatformRef; +export declare const serverTestPlatform: () => PlatformRef;