2016-06-23 09:47:54 -07:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2017-03-14 14:54:36 -07:00
|
|
|
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type, ɵConsole as Console, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵstringify as stringify} from '@angular/core';
|
2016-10-13 16:34:37 -07:00
|
|
|
|
2017-04-26 09:24:42 -07:00
|
|
|
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata';
|
2017-02-17 08:56:36 -08:00
|
|
|
import {CompilerConfig} from '../config';
|
2016-12-15 09:12:40 -08:00
|
|
|
import {CompilerInjectable} from '../injectable';
|
2016-11-14 17:37:47 -08:00
|
|
|
import {CompileMetadataResolver} from '../metadata_resolver';
|
|
|
|
import {NgModuleCompiler} from '../ng_module_compiler';
|
|
|
|
import * as ir from '../output/output_ast';
|
|
|
|
import {interpretStatements} from '../output/output_interpreter';
|
|
|
|
import {jitStatements} from '../output/output_jit';
|
|
|
|
import {CompiledStylesheet, StyleCompiler} from '../style_compiler';
|
2017-04-26 09:24:42 -07:00
|
|
|
import {SummaryResolver} from '../summary_resolver';
|
2016-11-14 17:37:47 -08:00
|
|
|
import {TemplateParser} from '../template_parser/template_parser';
|
2017-05-16 16:30:37 -07:00
|
|
|
import {OutputContext, SyncAsyncResult} from '../util';
|
2017-01-04 13:59:43 -08:00
|
|
|
import {ViewCompiler} from '../view_compiler/view_compiler';
|
2016-11-02 08:36:23 -07:00
|
|
|
|
2016-10-13 16:34:37 -07:00
|
|
|
|
2016-07-21 13:56:58 -07:00
|
|
|
|
2016-01-06 14:13:44 -08:00
|
|
|
/**
|
|
|
|
* An internal module of the Angular compiler that begins with component types,
|
|
|
|
* extracts templates, and eventually produces a compiled version of the component
|
|
|
|
* ready for linking into an application.
|
2016-06-28 11:01:35 -07:00
|
|
|
*
|
|
|
|
* @security When compiling templates at runtime, you must ensure that the entire template comes
|
|
|
|
* from a trusted source. Attacker-controlled data introduced by a template could expose your
|
|
|
|
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
2016-01-06 14:13:44 -08:00
|
|
|
*/
|
2016-12-15 09:12:40 -08:00
|
|
|
@CompilerInjectable()
|
2016-11-14 17:37:47 -08:00
|
|
|
export class JitCompiler implements Compiler {
|
2016-08-10 18:21:28 -07:00
|
|
|
private _compiledTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
|
|
|
private _compiledHostTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
2016-10-13 16:34:37 -07:00
|
|
|
private _compiledDirectiveWrapperCache = new Map<Type<any>, Type<any>>();
|
2016-08-10 18:21:28 -07:00
|
|
|
private _compiledNgModuleCache = new Map<Type<any>, NgModuleFactory<any>>();
|
2017-03-14 09:16:15 -07:00
|
|
|
private _sharedStylesheetCount = 0;
|
2016-07-08 13:40:54 -07:00
|
|
|
|
2016-06-08 16:38:52 -07:00
|
|
|
constructor(
|
2016-07-28 04:54:49 -07:00
|
|
|
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
2016-11-10 14:07:30 -08:00
|
|
|
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
|
|
|
private _viewCompiler: ViewCompiler, private _ngModuleCompiler: NgModuleCompiler,
|
2017-04-26 09:24:42 -07:00
|
|
|
private _summaryResolver: SummaryResolver<Type<any>>, private _compilerConfig: CompilerConfig,
|
|
|
|
private _console: Console) {}
|
2015-10-01 10:07:49 -07:00
|
|
|
|
2016-07-28 04:54:49 -07:00
|
|
|
get injector(): Injector { return this._injector; }
|
feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead. This reflects the
changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
`configureModule` and can no longer be provided via the
`PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and
now takes a `PlatformRef` and a factory for a
`Compiler`.
- E.g. 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 {setBaseTestProviders} from ‘@angular/core/testing’;
import {browserTestCompiler, browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
browserTestCompiler,
browserDynamicTestPlatform(),
BrowserDynamicTestModule);
```
- E.g. 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 {setBaseTestProviders} from ‘@angular/core/testing’;
import {serverTestCompiler, serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
serverTestCompiler,
serverTestPlatform(),
ServerTestModule);
```
Related to #9726
Closes #9846
2016-07-04 09:37:30 -07:00
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
2017-03-24 09:59:58 -07:00
|
|
|
return this._compileModuleAndComponents(moduleType, true).syncResult !;
|
2016-07-18 03:50:31 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
2017-03-24 09:59:58 -07:00
|
|
|
return this._compileModuleAndComponents(moduleType, false).asyncResult !;
|
2016-07-18 03:50:31 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
2017-03-24 09:59:58 -07:00
|
|
|
return this._compileModuleAndAllComponents(moduleType, true).syncResult !;
|
2016-07-28 04:54:49 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
2016-07-28 04:54:49 -07:00
|
|
|
Promise<ModuleWithComponentFactories<T>> {
|
2017-03-24 09:59:58 -07:00
|
|
|
return this._compileModuleAndAllComponents(moduleType, false).asyncResult !;
|
2016-07-28 04:54:49 -07:00
|
|
|
}
|
|
|
|
|
2016-11-02 22:38:00 +00:00
|
|
|
getNgContentSelectors(component: Type<any>): string[] {
|
2017-03-14 14:54:36 -07:00
|
|
|
this._console.warn(
|
|
|
|
'Compiler.getNgContentSelectors is deprecated. Use ComponentFactory.ngContentSelectors instead!');
|
2016-11-02 22:38:00 +00:00
|
|
|
const template = this._compiledTemplateCache.get(component);
|
|
|
|
if (!template) {
|
|
|
|
throw new Error(`The component ${stringify(component)} is not yet compiled!`);
|
|
|
|
}
|
2017-03-24 09:59:58 -07:00
|
|
|
return template.compMeta.template !.ngContentSelectors;
|
2016-11-02 22:38:00 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 09:24:42 -07:00
|
|
|
getComponentFactory<T>(component: Type<T>): ComponentFactory<T> {
|
|
|
|
const summary = this._metadataResolver.getDirectiveSummary(component);
|
|
|
|
return <ComponentFactory<T>>summary.componentFactory;
|
|
|
|
}
|
|
|
|
|
|
|
|
loadAotSummaries(summaries: () => any[]) {
|
|
|
|
this.clearCache();
|
|
|
|
flattenSummaries(summaries).forEach((summary) => {
|
|
|
|
this._summaryResolver.addSummary(
|
|
|
|
{symbol: summary.type.reference, metadata: null, type: summary});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
hasAotSummary(ref: Type<any>) { return !!this._summaryResolver.resolveSummary(ref); }
|
|
|
|
|
|
|
|
private _filterJitIdentifiers(ids: CompileIdentifierMetadata[]): any[] {
|
|
|
|
return ids.map(mod => mod.reference).filter((ref) => !this.hasAotSummary(ref));
|
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
|
2016-07-18 03:50:31 -07:00
|
|
|
SyncAsyncResult<NgModuleFactory<T>> {
|
2016-11-10 14:07:30 -08:00
|
|
|
const loadingPromise = this._loadModules(moduleType, isSync);
|
|
|
|
const createResult = () => {
|
|
|
|
this._compileComponents(moduleType, null);
|
|
|
|
return this._compileModule(moduleType);
|
|
|
|
};
|
|
|
|
if (isSync) {
|
|
|
|
return new SyncAsyncResult(createResult());
|
|
|
|
} else {
|
|
|
|
return new SyncAsyncResult(null, loadingPromise.then(createResult));
|
|
|
|
}
|
2016-06-28 09:54:42 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
private _compileModuleAndAllComponents<T>(moduleType: Type<T>, isSync: boolean):
|
2016-07-28 04:54:49 -07:00
|
|
|
SyncAsyncResult<ModuleWithComponentFactories<T>> {
|
2016-11-10 14:07:30 -08:00
|
|
|
const loadingPromise = this._loadModules(moduleType, isSync);
|
|
|
|
const createResult = () => {
|
|
|
|
const componentFactories: ComponentFactory<any>[] = [];
|
|
|
|
this._compileComponents(moduleType, componentFactories);
|
|
|
|
return new ModuleWithComponentFactories(this._compileModule(moduleType), componentFactories);
|
2016-07-28 04:54:49 -07:00
|
|
|
};
|
2016-11-10 14:07:30 -08:00
|
|
|
if (isSync) {
|
|
|
|
return new SyncAsyncResult(createResult());
|
|
|
|
} else {
|
|
|
|
return new SyncAsyncResult(null, loadingPromise.then(createResult));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private _loadModules(mainModule: any, isSync: boolean): Promise<any> {
|
2016-11-12 14:08:58 +01:00
|
|
|
const loadingPromises: Promise<any>[] = [];
|
2017-04-26 09:24:42 -07:00
|
|
|
const mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
|
|
|
|
// Note: for runtime compilation, we want to transitively compile all modules,
|
|
|
|
// so we also need to load the declared directives / pipes for all nested modules.
|
|
|
|
this._filterJitIdentifiers(mainNgModule.transitiveModule.modules).forEach((nestedNgModule) => {
|
|
|
|
// getNgModuleMetadata only returns null if the value passed in is not an NgModule
|
|
|
|
const moduleMeta = this._metadataResolver.getNgModuleMetadata(nestedNgModule) !;
|
|
|
|
this._filterJitIdentifiers(moduleMeta.declaredDirectives).forEach((ref) => {
|
|
|
|
const promise =
|
|
|
|
this._metadataResolver.loadDirectiveMetadata(moduleMeta.type.reference, ref, isSync);
|
|
|
|
if (promise) {
|
|
|
|
loadingPromises.push(promise);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this._filterJitIdentifiers(moduleMeta.declaredPipes)
|
|
|
|
.forEach((ref) => this._metadataResolver.getOrLoadPipeMetadata(ref));
|
2016-11-10 14:07:30 -08:00
|
|
|
});
|
|
|
|
return Promise.all(loadingPromises);
|
2016-07-28 04:54:49 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
private _compileModule<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
2017-03-24 09:59:58 -07:00
|
|
|
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType) !;
|
2016-07-18 03:50:31 -07:00
|
|
|
if (!ngModuleFactory) {
|
2017-03-24 09:59:58 -07:00
|
|
|
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType) !;
|
2016-08-16 16:48:32 -07:00
|
|
|
// Always provide a bound Compiler
|
|
|
|
const extraProviders = [this._metadataResolver.getProviderMetadata(new ProviderMeta(
|
2016-08-29 08:52:25 -07:00
|
|
|
Compiler, {useFactory: () => new ModuleBoundCompiler(this, moduleMeta.type.reference)}))];
|
2017-05-16 16:30:37 -07:00
|
|
|
const outputCtx = createOutputContext();
|
|
|
|
const compileResult = this._ngModuleCompiler.compile(outputCtx, moduleMeta, extraProviders);
|
2016-07-30 19:31:25 -07:00
|
|
|
if (!this._compilerConfig.useJit) {
|
2016-07-18 03:50:31 -07:00
|
|
|
ngModuleFactory =
|
2017-05-16 16:30:37 -07:00
|
|
|
interpretStatements(outputCtx.statements)[compileResult.ngModuleFactoryVar];
|
2016-06-28 09:54:42 -07:00
|
|
|
} else {
|
2016-07-18 03:50:31 -07:00
|
|
|
ngModuleFactory = jitStatements(
|
2017-05-16 16:30:37 -07:00
|
|
|
ngModuleJitUrl(moduleMeta), outputCtx.statements, )[compileResult.ngModuleFactoryVar];
|
2016-06-28 09:54:42 -07:00
|
|
|
}
|
2016-08-29 08:52:25 -07:00
|
|
|
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
|
2016-06-28 09:54:42 -07:00
|
|
|
}
|
2016-07-18 03:50:31 -07:00
|
|
|
return ngModuleFactory;
|
2016-06-24 08:46:43 -07:00
|
|
|
}
|
|
|
|
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
2017-03-24 09:59:58 -07:00
|
|
|
_compileComponents(mainModule: Type<any>, allComponentFactories: ComponentFactory<any>[]|null) {
|
|
|
|
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
|
2017-04-26 09:24:42 -07:00
|
|
|
const moduleByJitDirective = new Map<any, CompileNgModuleMetadata>();
|
2016-11-10 14:07:30 -08:00
|
|
|
const templates = new Set<CompiledTemplate>();
|
|
|
|
|
2017-04-26 09:24:42 -07:00
|
|
|
const transJitModules = this._filterJitIdentifiers(ngModule.transitiveModule.modules);
|
|
|
|
transJitModules.forEach((localMod) => {
|
|
|
|
const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod) !;
|
|
|
|
this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => {
|
|
|
|
moduleByJitDirective.set(dirRef, localModuleMeta);
|
|
|
|
const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef);
|
2016-07-18 03:50:31 -07:00
|
|
|
if (dirMeta.isComponent) {
|
2016-07-25 03:02:57 -07:00
|
|
|
templates.add(this._createCompiledTemplate(dirMeta, localModuleMeta));
|
2016-11-10 14:07:30 -08:00
|
|
|
if (allComponentFactories) {
|
|
|
|
const template =
|
|
|
|
this._createCompiledHostTemplate(dirMeta.type.reference, localModuleMeta);
|
|
|
|
templates.add(template);
|
2016-12-27 09:36:47 -08:00
|
|
|
allComponentFactories.push(<ComponentFactory<any>>dirMeta.componentFactory);
|
2016-11-10 14:07:30 -08:00
|
|
|
}
|
2016-10-13 16:34:37 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2017-04-26 09:24:42 -07:00
|
|
|
transJitModules.forEach((localMod) => {
|
|
|
|
const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod) !;
|
|
|
|
this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => {
|
|
|
|
const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef);
|
2016-10-13 16:34:37 -07:00
|
|
|
if (dirMeta.isComponent) {
|
2016-07-25 00:36:30 -07:00
|
|
|
dirMeta.entryComponents.forEach((entryComponentType) => {
|
2017-04-26 09:24:42 -07:00
|
|
|
const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType) !;
|
2016-10-13 16:34:37 -07:00
|
|
|
templates.add(
|
2016-12-27 09:36:47 -08:00
|
|
|
this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
|
2016-07-18 03:50:31 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2016-07-25 00:36:30 -07:00
|
|
|
localModuleMeta.entryComponents.forEach((entryComponentType) => {
|
2017-04-26 09:24:42 -07:00
|
|
|
if (!this.hasAotSummary(entryComponentType.componentType.reference)) {
|
|
|
|
const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType) !;
|
|
|
|
templates.add(
|
|
|
|
this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
|
|
|
|
}
|
2016-07-18 03:50:31 -07:00
|
|
|
});
|
|
|
|
});
|
2016-11-10 14:07:30 -08:00
|
|
|
templates.forEach((template) => this._compileTemplate(template));
|
2016-06-24 08:46:43 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
clearCacheFor(type: Type<any>) {
|
2016-07-18 03:50:31 -07:00
|
|
|
this._compiledNgModuleCache.delete(type);
|
2016-06-28 09:54:42 -07:00
|
|
|
this._metadataResolver.clearCacheFor(type);
|
|
|
|
this._compiledHostTemplateCache.delete(type);
|
2016-11-12 14:08:58 +01:00
|
|
|
const compiledTemplate = this._compiledTemplateCache.get(type);
|
2016-06-24 08:46:43 -07:00
|
|
|
if (compiledTemplate) {
|
2016-06-28 09:54:42 -07:00
|
|
|
this._compiledTemplateCache.delete(type);
|
2016-06-24 08:46:43 -07:00
|
|
|
}
|
2016-06-22 14:06:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
clearCache(): void {
|
2016-06-24 08:46:43 -07:00
|
|
|
this._metadataResolver.clearCache();
|
2016-06-22 14:06:23 -07:00
|
|
|
this._compiledTemplateCache.clear();
|
2016-06-24 08:46:43 -07:00
|
|
|
this._compiledHostTemplateCache.clear();
|
2016-07-18 03:50:31 -07:00
|
|
|
this._compiledNgModuleCache.clear();
|
2016-06-22 14:06:23 -07:00
|
|
|
}
|
2016-05-03 16:45:30 -07:00
|
|
|
|
2016-10-13 16:34:37 -07:00
|
|
|
private _createCompiledHostTemplate(compType: Type<any>, ngModule: CompileNgModuleMetadata):
|
|
|
|
CompiledTemplate {
|
|
|
|
if (!ngModule) {
|
|
|
|
throw new Error(
|
|
|
|
`Component ${stringify(compType)} is not part of any NgModule or the module has not been imported into your module.`);
|
|
|
|
}
|
2016-11-12 14:08:58 +01:00
|
|
|
let compiledTemplate = this._compiledHostTemplateCache.get(compType);
|
2016-09-30 09:26:53 -07:00
|
|
|
if (!compiledTemplate) {
|
2016-11-12 14:08:58 +01:00
|
|
|
const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
|
2016-01-06 14:13:44 -08:00
|
|
|
assertComponent(compMeta);
|
2016-11-23 09:42:19 -08:00
|
|
|
|
2016-12-27 09:36:47 -08:00
|
|
|
const componentFactory = <ComponentFactory<any>>compMeta.componentFactory;
|
|
|
|
const hostClass = this._metadataResolver.getHostComponentType(compType);
|
|
|
|
const hostMeta = createHostComponentMeta(
|
2017-02-27 23:08:19 -08:00
|
|
|
hostClass, compMeta, <any>getComponentViewDefinitionFactory(componentFactory));
|
2016-12-27 09:36:47 -08:00
|
|
|
compiledTemplate =
|
|
|
|
new CompiledTemplate(true, compMeta.type, hostMeta, ngModule, [compMeta.type]);
|
2016-07-18 03:50:31 -07:00
|
|
|
this._compiledHostTemplateCache.set(compType, compiledTemplate);
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
2016-06-24 08:46:43 -07:00
|
|
|
return compiledTemplate;
|
2015-10-01 10:07:49 -07:00
|
|
|
}
|
|
|
|
|
2016-06-28 09:54:42 -07:00
|
|
|
private _createCompiledTemplate(
|
2016-07-25 03:02:57 -07:00
|
|
|
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata): CompiledTemplate {
|
2016-11-12 14:08:58 +01:00
|
|
|
let compiledTemplate = this._compiledTemplateCache.get(compMeta.type.reference);
|
2016-09-30 09:26:53 -07:00
|
|
|
if (!compiledTemplate) {
|
2016-06-24 08:46:43 -07:00
|
|
|
assertComponent(compMeta);
|
|
|
|
compiledTemplate = new CompiledTemplate(
|
2016-12-27 09:36:47 -08:00
|
|
|
false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);
|
2016-08-29 08:52:25 -07:00
|
|
|
this._compiledTemplateCache.set(compMeta.type.reference, compiledTemplate);
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
return compiledTemplate;
|
|
|
|
}
|
|
|
|
|
2016-06-24 08:46:43 -07:00
|
|
|
private _compileTemplate(template: CompiledTemplate) {
|
|
|
|
if (template.isCompiled) {
|
|
|
|
return;
|
|
|
|
}
|
2016-11-10 14:07:30 -08:00
|
|
|
const compMeta = template.compMeta;
|
2016-07-13 11:01:32 -07:00
|
|
|
const externalStylesheetsByModuleUrl = new Map<string, CompiledStylesheet>();
|
2017-05-16 16:30:37 -07:00
|
|
|
const outputContext = createOutputContext();
|
|
|
|
const componentStylesheet = this._styleCompiler.compileComponent(outputContext, compMeta);
|
|
|
|
compMeta.template !.externalStylesheets.forEach((stylesheetMeta) => {
|
|
|
|
const compiledStylesheet =
|
|
|
|
this._styleCompiler.compileStyles(createOutputContext(), compMeta, stylesheetMeta);
|
|
|
|
externalStylesheetsByModuleUrl.set(stylesheetMeta.moduleUrl !, compiledStylesheet);
|
|
|
|
});
|
|
|
|
this._resolveStylesCompileResult(componentStylesheet, externalStylesheetsByModuleUrl);
|
2016-11-10 14:07:30 -08:00
|
|
|
const directives =
|
2016-11-10 16:27:53 -08:00
|
|
|
template.directives.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
|
2016-11-10 14:07:30 -08:00
|
|
|
const pipes = template.ngModule.transitiveModule.pipes.map(
|
2016-11-10 16:27:53 -08:00
|
|
|
pipe => this._metadataResolver.getPipeSummary(pipe.reference));
|
2017-02-09 14:59:57 -08:00
|
|
|
const {template: parsedTemplate, pipes: usedPipes} = this._templateParser.parse(
|
2017-03-24 09:59:58 -07:00
|
|
|
compMeta, compMeta.template !.template !, directives, pipes, template.ngModule.schemas,
|
|
|
|
templateSourceUrl(template.ngModule.type, template.compMeta, template.compMeta.template !));
|
2016-07-13 11:01:32 -07:00
|
|
|
const compileResult = this._viewCompiler.compileComponent(
|
2017-05-16 16:30:37 -07:00
|
|
|
outputContext, compMeta, parsedTemplate, ir.variable(componentStylesheet.stylesVar),
|
2017-02-27 23:08:19 -08:00
|
|
|
usedPipes);
|
2017-05-16 16:30:37 -07:00
|
|
|
let evalResult: any;
|
2016-07-30 19:31:25 -07:00
|
|
|
if (!this._compilerConfig.useJit) {
|
2017-05-16 16:30:37 -07:00
|
|
|
evalResult = interpretStatements(outputContext.statements);
|
2016-01-06 14:13:44 -08:00
|
|
|
} else {
|
2017-05-16 16:30:37 -07:00
|
|
|
evalResult = jitStatements(
|
|
|
|
templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
2017-05-16 16:30:37 -07:00
|
|
|
const viewClass = evalResult[compileResult.viewClassVar];
|
|
|
|
const rendererType = evalResult[compileResult.rendererTypeVar];
|
2017-02-17 09:01:37 -08:00
|
|
|
template.compiled(viewClass, rendererType);
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
|
2016-06-24 08:46:43 -07:00
|
|
|
private _resolveStylesCompileResult(
|
|
|
|
result: CompiledStylesheet, externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>) {
|
|
|
|
result.dependencies.forEach((dep, i) => {
|
2017-03-24 09:59:58 -07:00
|
|
|
const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl) !;
|
2016-11-12 14:08:58 +01:00
|
|
|
const nestedStylesArr = this._resolveAndEvalStylesCompileResult(
|
2016-06-24 08:46:43 -07:00
|
|
|
nestedCompileResult, externalStylesheetsByModuleUrl);
|
2017-05-16 16:30:37 -07:00
|
|
|
dep.setValue(nestedStylesArr);
|
2016-06-24 08:46:43 -07:00
|
|
|
});
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
|
2016-06-24 08:46:43 -07:00
|
|
|
private _resolveAndEvalStylesCompileResult(
|
|
|
|
result: CompiledStylesheet,
|
|
|
|
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
|
|
|
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
2016-07-30 19:31:25 -07:00
|
|
|
if (!this._compilerConfig.useJit) {
|
2017-05-16 16:30:37 -07:00
|
|
|
return interpretStatements(result.outputCtx.statements)[result.stylesVar];
|
2016-06-24 08:46:43 -07:00
|
|
|
} else {
|
2016-12-13 17:44:52 -08:00
|
|
|
return jitStatements(
|
2017-05-16 16:30:37 -07:00
|
|
|
sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++),
|
|
|
|
result.outputCtx.statements)[result.stylesVar];
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
2016-06-22 14:06:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-06 14:13:44 -08:00
|
|
|
class CompiledTemplate {
|
2017-03-24 09:59:58 -07:00
|
|
|
private _viewClass: Function = null !;
|
2016-06-24 08:46:43 -07:00
|
|
|
isCompiled = false;
|
|
|
|
|
|
|
|
constructor(
|
2016-12-27 09:36:47 -08:00
|
|
|
public isHost: boolean, public compType: CompileIdentifierMetadata,
|
2016-11-10 14:07:30 -08:00
|
|
|
public compMeta: CompileDirectiveMetadata, public ngModule: CompileNgModuleMetadata,
|
2017-01-04 13:59:43 -08:00
|
|
|
public directives: CompileIdentifierMetadata[]) {}
|
2016-06-24 08:46:43 -07:00
|
|
|
|
2017-02-17 09:01:37 -08:00
|
|
|
compiled(viewClass: Function, rendererType: any) {
|
2016-11-02 08:36:23 -07:00
|
|
|
this._viewClass = viewClass;
|
2016-12-27 09:36:47 -08:00
|
|
|
(<ProxyClass>this.compMeta.componentViewType).setDelegate(viewClass);
|
2017-02-17 09:01:37 -08:00
|
|
|
for (let prop in rendererType) {
|
|
|
|
(<any>this.compMeta.rendererType)[prop] = rendererType[prop];
|
2017-02-16 13:55:55 -08:00
|
|
|
}
|
2016-06-24 08:46:43 -07:00
|
|
|
this.isCompiled = true;
|
2016-01-06 14:13:44 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertComponent(meta: CompileDirectiveMetadata) {
|
|
|
|
if (!meta.isComponent) {
|
2016-11-23 09:42:19 -08:00
|
|
|
throw new Error(
|
|
|
|
`Could not compile '${identifierName(meta.type)}' because it is not a component.`);
|
2015-10-01 10:07:49 -07:00
|
|
|
}
|
|
|
|
}
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
|
|
|
|
/**
|
2016-11-14 17:37:47 -08:00
|
|
|
* Implements `Compiler` by delegating to the JitCompiler using a known module.
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
*/
|
2016-08-16 16:48:32 -07:00
|
|
|
class ModuleBoundCompiler implements Compiler {
|
2016-11-14 17:37:47 -08:00
|
|
|
constructor(private _delegate: JitCompiler, private _ngModule: Type<any>) {}
|
feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead. This reflects the
changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
`configureModule` and can no longer be provided via the
`PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and
now takes a `PlatformRef` and a factory for a
`Compiler`.
- E.g. 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 {setBaseTestProviders} from ‘@angular/core/testing’;
import {browserTestCompiler, browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
browserTestCompiler,
browserDynamicTestPlatform(),
BrowserDynamicTestModule);
```
- E.g. 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 {setBaseTestProviders} from ‘@angular/core/testing’;
import {serverTestCompiler, serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
serverTestCompiler,
serverTestPlatform(),
ServerTestModule);
```
Related to #9726
Closes #9846
2016-07-04 09:37:30 -07:00
|
|
|
|
2016-07-28 04:54:49 -07:00
|
|
|
get _injector(): Injector { return this._delegate.injector; }
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
2016-07-18 03:50:31 -07:00
|
|
|
return this._delegate.compileModuleSync(moduleType);
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
2016-07-18 03:50:31 -07:00
|
|
|
return this._delegate.compileModuleAsync(moduleType);
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
}
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
2016-07-28 04:54:49 -07:00
|
|
|
return this._delegate.compileModuleAndAllComponentsSync(moduleType);
|
|
|
|
}
|
|
|
|
|
2016-08-10 18:21:28 -07:00
|
|
|
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
2016-07-28 04:54:49 -07:00
|
|
|
Promise<ModuleWithComponentFactories<T>> {
|
|
|
|
return this._delegate.compileModuleAndAllComponentsAsync(moduleType);
|
|
|
|
}
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
|
2016-11-02 22:38:00 +00:00
|
|
|
getNgContentSelectors(component: Type<any>): string[] {
|
|
|
|
return this._delegate.getNgContentSelectors(component);
|
|
|
|
}
|
|
|
|
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
/**
|
|
|
|
* Clears all caches
|
|
|
|
*/
|
2016-08-16 16:48:32 -07:00
|
|
|
clearCache(): void { this._delegate.clearCache(); }
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
|
|
|
|
/**
|
2016-07-18 03:50:31 -07:00
|
|
|
* Clears the cache for the given component/ngModule.
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@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 {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 13:07:17 -07:00
|
|
|
*/
|
2016-08-10 18:21:28 -07:00
|
|
|
clearCacheFor(type: Type<any>) { this._delegate.clearCacheFor(type); }
|
2016-07-18 03:50:31 -07:00
|
|
|
}
|
2017-04-26 09:24:42 -07:00
|
|
|
|
|
|
|
|
|
|
|
function flattenSummaries(fn: () => any[], out: CompileTypeSummary[] = []): CompileTypeSummary[] {
|
|
|
|
fn().forEach((entry) => {
|
|
|
|
if (typeof entry === 'function') {
|
|
|
|
flattenSummaries(entry, out);
|
|
|
|
} else {
|
|
|
|
out.push(entry);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return out;
|
|
|
|
}
|
2017-05-16 16:30:37 -07:00
|
|
|
|
|
|
|
function createOutputContext(): OutputContext {
|
|
|
|
const importExpr = (symbol: any) =>
|
|
|
|
ir.importExpr({name: identifierName(symbol), moduleName: null, runtime: symbol});
|
|
|
|
return {statements: [], genFilePath: '', importExpr};
|
|
|
|
}
|