From cf0e3c6bbf428e545e16f13433503d04304edb83 Mon Sep 17 00:00:00 2001 From: Olivier Combe Date: Wed, 15 Nov 2017 18:22:23 +0100 Subject: [PATCH] feat(platform-browser-dynamic): export `JitCompilerFactory` (#20478) Fixes #20125 PR Close #20478 --- .../dynamic-compiler/e2e/app.e2e-spec.ts | 19 ++++++++ integration/dynamic-compiler/e2e/app.po.ts | 16 +++++++ .../dynamic-compiler/e2e/browser.config.json | 15 +++++++ .../dynamic-compiler/e2e/protractor.config.js | 16 +++++++ .../dynamic-compiler/e2e/tsconfig.json | 7 +++ integration/dynamic-compiler/index.html | 14 ++++++ integration/dynamic-compiler/package.json | 44 +++++++++++++++++++ integration/dynamic-compiler/rollup.config.js | 17 +++++++ .../dynamic-compiler/rollup.lazy.config.js | 19 ++++++++ .../dynamic-compiler/src/app.component.ts | 27 ++++++++++++ .../dynamic-compiler/src/app.module.ts | 22 ++++++++++ .../dynamic-compiler/src/lazy.module.ts | 17 +++++++ integration/dynamic-compiler/src/main.ts | 8 ++++ integration/dynamic-compiler/tsconfig.json | 28 ++++++++++++ .../src/compiler_factory.ts | 5 +++ .../src/platform-browser-dynamic.ts | 1 + .../platform-browser-dynamic.d.ts | 5 +++ 17 files changed, 280 insertions(+) create mode 100644 integration/dynamic-compiler/e2e/app.e2e-spec.ts create mode 100644 integration/dynamic-compiler/e2e/app.po.ts create mode 100644 integration/dynamic-compiler/e2e/browser.config.json create mode 100644 integration/dynamic-compiler/e2e/protractor.config.js create mode 100644 integration/dynamic-compiler/e2e/tsconfig.json create mode 100644 integration/dynamic-compiler/index.html create mode 100644 integration/dynamic-compiler/package.json create mode 100644 integration/dynamic-compiler/rollup.config.js create mode 100644 integration/dynamic-compiler/rollup.lazy.config.js create mode 100644 integration/dynamic-compiler/src/app.component.ts create mode 100644 integration/dynamic-compiler/src/app.module.ts create mode 100644 integration/dynamic-compiler/src/lazy.module.ts create mode 100644 integration/dynamic-compiler/src/main.ts create mode 100644 integration/dynamic-compiler/tsconfig.json diff --git a/integration/dynamic-compiler/e2e/app.e2e-spec.ts b/integration/dynamic-compiler/e2e/app.e2e-spec.ts new file mode 100644 index 0000000000000..654e76298f184 --- /dev/null +++ b/integration/dynamic-compiler/e2e/app.e2e-spec.ts @@ -0,0 +1,19 @@ +import { AppPage } from './app.po'; + +describe('dynamic-compiler App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('Hello world!'); + }); + + it('should display lazy-loaded component', () => { + page.navigateTo(); + expect(page.getLazyLoadedText()).toEqual('Lazy-loaded component!'); + }); +}); diff --git a/integration/dynamic-compiler/e2e/app.po.ts b/integration/dynamic-compiler/e2e/app.po.ts new file mode 100644 index 0000000000000..af43732cc6f24 --- /dev/null +++ b/integration/dynamic-compiler/e2e/app.po.ts @@ -0,0 +1,16 @@ +import {browser, by, element, protractor} from 'protractor'; + +export class AppPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } + + getLazyLoadedText() { + const el = element(by.css('app-root lazy-component')); + return browser.wait(protractor.ExpectedConditions.presenceOf(el)).then(() => el.getText(), err => el.getText()); + } +} diff --git a/integration/dynamic-compiler/e2e/browser.config.json b/integration/dynamic-compiler/e2e/browser.config.json new file mode 100644 index 0000000000000..44f23aa0092cc --- /dev/null +++ b/integration/dynamic-compiler/e2e/browser.config.json @@ -0,0 +1,15 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": ".", + "routes": { + "/dist": "dist", + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/integration/dynamic-compiler/e2e/protractor.config.js b/integration/dynamic-compiler/e2e/protractor.config.js new file mode 100644 index 0000000000000..9b7d88e74139d --- /dev/null +++ b/integration/dynamic-compiler/e2e/protractor.config.js @@ -0,0 +1,16 @@ +exports.config = { + specs: [ + '../dist/e2e/*.e2e-spec.js' + ], + capabilities: { + browserName: 'chrome', + chromeOptions: { + args: ['--no-sandbox'], + binary: process.env.CHROME_BIN, + } + }, + directConnect: true, + baseUrl: 'http://localhost:8080/', + framework: 'jasmine', + useAllAngular2AppRoots: true +}; diff --git a/integration/dynamic-compiler/e2e/tsconfig.json b/integration/dynamic-compiler/e2e/tsconfig.json new file mode 100644 index 0000000000000..2badee6f7a20a --- /dev/null +++ b/integration/dynamic-compiler/e2e/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "outDir": "../dist/e2e", + "types": ["jasmine"], + "skipLibCheck": true + } +} diff --git a/integration/dynamic-compiler/index.html b/integration/dynamic-compiler/index.html new file mode 100644 index 0000000000000..6c291a4a5f2a0 --- /dev/null +++ b/integration/dynamic-compiler/index.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/integration/dynamic-compiler/package.json b/integration/dynamic-compiler/package.json new file mode 100644 index 0000000000000..59b2de6980cd9 --- /dev/null +++ b/integration/dynamic-compiler/package.json @@ -0,0 +1,44 @@ +{ + "name": "dynamic-compiler", + "version": "0.0.0", + "main": "index.js", + "scripts": { + "build": "npm run clean && npm run ngc && npm run rollup && npm run rollup:lazy && npm run es5 && npm run es5:lazy", + "clean": "rm -rf dist", + "es5": "tsc --target es5 --skipLibCheck --allowJs dist/bundle.es2015.js --out dist/bundle.js", + "es5:lazy": "tsc --target es5 --skipLibCheck --allowJs dist/lazy.bundle.es2015.js --out dist/lazy.bundle.js", + "ngc": "ngc -p tsconfig.json", + "rollup": "rollup -f iife -c rollup.config.js -o dist/bundle.es2015.js", + "rollup:lazy": "rollup -f cjs -c rollup.lazy.config.js -o dist/lazy.bundle.es2015.js", + "postinstall": "webdriver-manager update --gecko false", + "preprotractor": "tsc -p e2e", + "protractor": "protractor e2e/protractor.config.js", + "serve": "lite-server -c e2e/browser.config.json", + "test": "npm run build && concurrently \"yarn run serve\" \"yarn run protractor\" --kill-others --success first" + }, + "license": "MIT", + "devDependencies": { + "@types/jasmine": "file:../../node_modules/@types/jasmine", + "@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli", + "concurrently": "3.4.0", + "lite-server": "2.2.2", + "protractor": "file:../../node_modules/protractor", + "rollup": "file:../../node_modules/rollup", + "rollup-plugin-commonjs": "file:../../node_modules/rollup-plugin-commonjs", + "rollup-plugin-node-resolve": "file:../../node_modules/rollup-plugin-node-resolve", + "typescript": "file:../../node_modules/typescript" + }, + "dependencies": { + "@angular/animations": "file:../../dist/packages-dist/animations", + "@angular/common": "file:../../dist/packages-dist/common", + "@angular/compiler": "file:../../dist/packages-dist/compiler", + "@angular/core": "file:../../dist/packages-dist/core", + "@angular/platform-browser": "file:../../dist/packages-dist/platform-browser", + "@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic", + "@angular/platform-server": "file:../../dist/packages-dist/platform-server", + "core-js": "file:../../node_modules/core-js", + "rxjs": "file:../../node_modules/rxjs", + "systemjs": "file:../../node_modules/systemjs", + "zone.js": "file:../../node_modules/zone.js" + } +} diff --git a/integration/dynamic-compiler/rollup.config.js b/integration/dynamic-compiler/rollup.config.js new file mode 100644 index 0000000000000..99a80d844a93b --- /dev/null +++ b/integration/dynamic-compiler/rollup.config.js @@ -0,0 +1,17 @@ +import nodeResolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; + +export default { + entry: 'dist/src/main.js', + sourceMap: true, + treeshake: true, + moduleName: 'main', + plugins: [ + commonjs({ + include: 'node_modules/**' + }), + nodeResolve({ + jsnext: true, main: true, module: true + }) + ] +}; diff --git a/integration/dynamic-compiler/rollup.lazy.config.js b/integration/dynamic-compiler/rollup.lazy.config.js new file mode 100644 index 0000000000000..d44ea0dd832ce --- /dev/null +++ b/integration/dynamic-compiler/rollup.lazy.config.js @@ -0,0 +1,19 @@ +import nodeResolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; + +// a real app should make a common bundle for libraries instead of bundling them +// in both the main module & the lazy module, but we don't care about size here +export default { + entry: 'dist/src/lazy.module.js', + sourceMap: true, + treeshake: true, + moduleName: 'lazy', + plugins: [ + commonjs({ + include: 'node_modules/**' + }), + nodeResolve({ + jsnext: true, main: true, module: true + }) + ] +}; diff --git a/integration/dynamic-compiler/src/app.component.ts b/integration/dynamic-compiler/src/app.component.ts new file mode 100644 index 0000000000000..e54316da9be15 --- /dev/null +++ b/integration/dynamic-compiler/src/app.component.ts @@ -0,0 +1,27 @@ +import {AfterViewInit, Compiler, Component, ViewChild, ViewContainerRef} from '@angular/core'; + +declare var System: any; + +@Component({ + selector: 'app-root', + template: ` +

Hello world!

+
+ `, +}) +export class AppComponent implements AfterViewInit { + @ViewChild('vc', {read: ViewContainerRef}) container: ViewContainerRef; + + constructor(private compiler: Compiler) { + } + + ngAfterViewInit() { + System.import('./dist/lazy.bundle.js').then((module: any) => { + this.compiler.compileModuleAndAllComponentsAsync(module.LazyModule) + .then((compiled) => { + const factory = compiled.componentFactories[0]; + this.container.createComponent(factory); + }); + }); + } +} diff --git a/integration/dynamic-compiler/src/app.module.ts b/integration/dynamic-compiler/src/app.module.ts new file mode 100644 index 0000000000000..0963654c9522c --- /dev/null +++ b/integration/dynamic-compiler/src/app.module.ts @@ -0,0 +1,22 @@ +import {Compiler, COMPILER_OPTIONS, CompilerFactory, NgModule} from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import {JitCompilerFactory} from '@angular/platform-browser-dynamic'; + +import { AppComponent } from './app.component'; + +export function createCompiler(compilerFactory: CompilerFactory) { + return compilerFactory.createCompiler(); +} + +@NgModule({ + imports: [BrowserModule], + bootstrap: [AppComponent], + declarations: [AppComponent], + providers: [ + {provide: COMPILER_OPTIONS, useValue: {}, multi: true}, + {provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]}, + {provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory]} + ] +}) +export class AppModule {} + diff --git a/integration/dynamic-compiler/src/lazy.module.ts b/integration/dynamic-compiler/src/lazy.module.ts new file mode 100644 index 0000000000000..876cf05f4a22b --- /dev/null +++ b/integration/dynamic-compiler/src/lazy.module.ts @@ -0,0 +1,17 @@ +import {NgModule} from "@angular/core"; +import {Component} from '@angular/core'; + +@Component({ + selector: 'lazy-component', + template: 'Lazy-loaded component!' +}) +export class LazyComponent { + constructor() { + } +} + +@NgModule({ + declarations: [LazyComponent] +}) +export class LazyModule { +} diff --git a/integration/dynamic-compiler/src/main.ts b/integration/dynamic-compiler/src/main.ts new file mode 100644 index 0000000000000..7c5e5943c3547 --- /dev/null +++ b/integration/dynamic-compiler/src/main.ts @@ -0,0 +1,8 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowser } from '@angular/platform-browser'; + +import { AppModuleNgFactory } from './app.module.ngfactory'; + +enableProdMode(); + +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); diff --git a/integration/dynamic-compiler/tsconfig.json b/integration/dynamic-compiler/tsconfig.json new file mode 100644 index 0000000000000..4adfea7714c53 --- /dev/null +++ b/integration/dynamic-compiler/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "es2015", + "moduleResolution": "node", + "declaration": false, + "removeComments": true, + "noLib": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es6", "es2015", "dom"], + "sourceMap": true, + "pretty": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noFallthroughCasesInSwitch": true, + "outDir": "./dist", + "types": [ + ] + }, + "files": [ + "src/main.ts", + "src/lazy.module.ts" + ] +} diff --git a/packages/platform-browser-dynamic/src/compiler_factory.ts b/packages/platform-browser-dynamic/src/compiler_factory.ts index f19467a765bc9..2160a147cf717 100644 --- a/packages/platform-browser-dynamic/src/compiler_factory.ts +++ b/packages/platform-browser-dynamic/src/compiler_factory.ts @@ -150,8 +150,13 @@ export const COMPILER_PROVIDERS = [ { provide: NgModuleResolver, deps: [CompileReflector]}, ]; +/** + * @experimental + */ export class JitCompilerFactory implements CompilerFactory { private _defaultOptions: CompilerOptions[]; + + /* @internal */ constructor(defaultOptions: CompilerOptions[]) { const compilerOptions: CompilerOptions = { useJit: true, diff --git a/packages/platform-browser-dynamic/src/platform-browser-dynamic.ts b/packages/platform-browser-dynamic/src/platform-browser-dynamic.ts index a97968ce93d17..654164134aba2 100644 --- a/packages/platform-browser-dynamic/src/platform-browser-dynamic.ts +++ b/packages/platform-browser-dynamic/src/platform-browser-dynamic.ts @@ -15,6 +15,7 @@ import {CachedResourceLoader} from './resource_loader/resource_loader_cache'; export * from './private_export'; export {VERSION} from './version'; +export {JitCompilerFactory} from './compiler_factory'; /** * @experimental diff --git a/tools/public_api_guard/platform-browser-dynamic/platform-browser-dynamic.d.ts b/tools/public_api_guard/platform-browser-dynamic/platform-browser-dynamic.d.ts index 414918714bd62..1b02d8e0e598c 100644 --- a/tools/public_api_guard/platform-browser-dynamic/platform-browser-dynamic.d.ts +++ b/tools/public_api_guard/platform-browser-dynamic/platform-browser-dynamic.d.ts @@ -1,3 +1,8 @@ +/** @experimental */ +export declare class JitCompilerFactory implements CompilerFactory { + createCompiler(options?: CompilerOptions[]): Compiler; +} + /** @stable */ export declare const platformBrowserDynamic: (extraProviders?: StaticProvider[] | undefined) => PlatformRef;