diff --git a/public/docs/_examples/inheritance/ts/.gitignore b/public/docs/_examples/inheritance/ts/.gitignore new file mode 100644 index 0000000000..c20819f579 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/.gitignore @@ -0,0 +1,7 @@ +**/*.ngfactory.ts +**/*.ngsummary.json +**/*.metadata.json +**/*.shim.ngstyle.ts +dist +!app/tsconfig.json +!rollup-config.js diff --git a/public/docs/_examples/inheritance/ts/README.md b/public/docs/_examples/inheritance/ts/README.md new file mode 100644 index 0000000000..d9172050ff --- /dev/null +++ b/public/docs/_examples/inheritance/ts/README.md @@ -0,0 +1,40 @@ +# Angular Inheritance Sample (draft) + +The AOT Cookbook sample was the starting point. +This sample runs in both JIT and AOT + +With AOT you have to re-build after each change. +With JIT you can develop on the fly as we usually do. + +## Inheritance experiments +Look at `sub.component.ts` to see the experiments in metadata inheritance. + + +## Building it + +The original source is in https://github.com/angular/angular.io/pull/3096 along with +tools and configs to build it in JIT and AOT. +You'll need knowledge of the Angular docs sample development practices to do it. + +Commands to run: + +``` +# compile with AOT, then rollup. Noisy. +npm run build:aot + +# start server and JIT/TS watching as usual +npm start +``` +The browser displays the JIT version (`index.html`) by default. +You can tell by looking at the browser tab (it says "JIT:..."), in the console, and in the page header. + +To see the AOT version, put `index-aot.html` in the address bar. +You can tell by looking at the browser tab (it says "AOT:..."), in the console, and in the page header. + +## Running it + +I like to have two console windows open: + +1. Running `npm start` (after once having run `npm run build:aot`) + +1. Where I periodically re-run either `npm run tsc` or `npm run build:aot` after a change that works in JIT diff --git a/public/docs/_examples/inheritance/ts/app/app.component.html b/public/docs/_examples/inheritance/ts/app/app.component.html new file mode 100644 index 0000000000..0601c5d61f --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/app.component.html @@ -0,0 +1,5 @@ + +

Angular Inheritance ({{buildMode}})

+ + + diff --git a/public/docs/_examples/inheritance/ts/app/app.component.ts b/public/docs/_examples/inheritance/ts/app/app.component.ts new file mode 100644 index 0000000000..a14db88f33 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/app.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { + buildMode = document['aot'] ? 'AOT' : 'JIT'; +} + diff --git a/public/docs/_examples/inheritance/ts/app/app.module.ts b/public/docs/_examples/inheritance/ts/app/app.module.ts new file mode 100644 index 0000000000..3afa43803f --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { BaseComponent } from './base.component'; +import { SubComponent } from './sub.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + AppComponent, + BaseComponent, + SubComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/inheritance/ts/app/base.component.css b/public/docs/_examples/inheritance/ts/app/base.component.css new file mode 100644 index 0000000000..37e22e4ebf --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/base.component.css @@ -0,0 +1 @@ +#speak { font-style: italic; color: blue; } diff --git a/public/docs/_examples/inheritance/ts/app/base.component.ts b/public/docs/_examples/inheritance/ts/app/base.component.ts new file mode 100644 index 0000000000..670eddbe02 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/base.component.ts @@ -0,0 +1,35 @@ +import { Component, Input, Injectable } from '@angular/core'; + +@Injectable() +export class ServiceA { + name = 'Service A'; +} + +@Injectable() +export class ServiceB { + name = 'Service B'; +} + +export const BASE_PROVIDERS = [ ServiceA, ServiceB ]; + +export const BASE_METADATA = { + moduleId: module.id, + selector: 'base-comp', + template: ` +

{{speaker}} sez:

+

I am the base component. Koo-koo-ka-choo.

+

{{services}}

+ `, + styleUrls: [ './base.component.css'] , + providers: [BASE_PROVIDERS] +}; + +@Component(BASE_METADATA) +export class BaseComponent { + @Input() speaker: string; + services: string; + + constructor(private a: ServiceA, private b: ServiceB) { + this.services = `ServiceA is ${a.name}; Service B is ${b.name}`; + } +} diff --git a/public/docs/_examples/inheritance/ts/app/main-aot.ts b/public/docs/_examples/inheritance/ts/app/main-aot.ts new file mode 100644 index 0000000000..8184fabe20 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/main-aot.ts @@ -0,0 +1,7 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; +import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory'; + +console.log('Running AOT version'); +document['aot'] = true; +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); diff --git a/public/docs/_examples/inheritance/ts/app/main.ts b/public/docs/_examples/inheritance/ts/app/main.ts new file mode 100644 index 0000000000..e3f504f2b8 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/main.ts @@ -0,0 +1,7 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app.module'; + +console.log('Running JIT version'); +document['aot'] = false; +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/inheritance/ts/app/sub.component.ts b/public/docs/_examples/inheritance/ts/app/sub.component.ts new file mode 100644 index 0000000000..1a36a3c6d8 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/app/sub.component.ts @@ -0,0 +1,69 @@ +import { Component, Injectable } from '@angular/core'; + +import { BaseComponent, BASE_METADATA, BASE_PROVIDERS, ServiceA } from './base.component'; + +///////// SubComponent service substitution //// +@Injectable() +export class ServiceASub { + name = 'A-sub'; +} + +///////// SubComponent Metadata Trials //// + +// The intended, fully specified SubComponent metadat. We know this works +const subMeta = { + moduleId: module.id, + selector: 'sub-comp', + template: ` +

{{speaker}} sez:

+

I am the SUB component. Hear me roar.

+

{{services}}

+ `, + styleUrls: [ './base.component.css'] , + providers: [ + BASE_PROVIDERS, + {provide: ServiceA, useClass: ServiceASub} + ] +}; + +//////////////////// +// This works in JIT but not AOT +export function blendMetadata() { + return Object.assign({}, BASE_METADATA, subMeta); +} + +////////////////////////// +// Manual inheritance +const inheritMetadata = { + // inherit (silly) + moduleId: BASE_METADATA.moduleId, + + // Override + selector: 'sub-comp', + template: ` +

{{speaker}} sez:

+

I am the SUB component. Hear me roar.

+

{{services}}

+ `, + + // Extend providers (actually overrides) + providers: [ + BASE_METADATA.providers, // inherit + {provide: ServiceA, useClass: ServiceASub} + ], + + // Inherit + styleUrls: BASE_METADATA.styleUrls // inherit +}; + +////////////// SubComponent //////////////////////// + +// This works in JIT and AOT +// @Component(subMeta) + +// This works in JIT but not AOT +// @Component(blendMetadata()) + +// This works in JIT and AOT +@Component(inheritMetadata) +export class SubComponent extends BaseComponent { } diff --git a/public/docs/_examples/inheritance/ts/example-config.json b/public/docs/_examples/inheritance/ts/example-config.json new file mode 100644 index 0000000000..1ef73390ce --- /dev/null +++ b/public/docs/_examples/inheritance/ts/example-config.json @@ -0,0 +1,4 @@ +{ + "build": "build:aot", + "run": "http-server:e2e" +} \ No newline at end of file diff --git a/public/docs/_examples/inheritance/ts/index-aot.html b/public/docs/_examples/inheritance/ts/index-aot.html new file mode 100644 index 0000000000..25fed2c421 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/index-aot.html @@ -0,0 +1,24 @@ + + + + + AOT: Angular Inheritance + + + + + + + + + + + + + + Loading... + + + + + diff --git a/public/docs/_examples/inheritance/ts/index.html b/public/docs/_examples/inheritance/ts/index.html new file mode 100644 index 0000000000..a1bdc3b41f --- /dev/null +++ b/public/docs/_examples/inheritance/ts/index.html @@ -0,0 +1,24 @@ + + + + JIT: Angular Inheritance + + + + + + + + + + + + + + + Loading AppComponent content here ... + + + diff --git a/public/docs/_examples/inheritance/ts/plnkr.json b/public/docs/_examples/inheritance/ts/plnkr.json new file mode 100644 index 0000000000..bbb4743c4e --- /dev/null +++ b/public/docs/_examples/inheritance/ts/plnkr.json @@ -0,0 +1,10 @@ +{ + "description": "App", + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!app/main-aot.ts", + "!README.md" + ], + "tags": ["inheritance"] +} diff --git a/public/docs/_examples/inheritance/ts/rollup-config.js b/public/docs/_examples/inheritance/ts/rollup-config.js new file mode 100644 index 0000000000..342c00b2c6 --- /dev/null +++ b/public/docs/_examples/inheritance/ts/rollup-config.js @@ -0,0 +1,36 @@ +// #docregion +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +// #docregion config +export default { + entry: 'app/main-aot.js', + dest: 'dist/build.js', // output a single application bundle + sourceMap: false, + format: 'iife', + onwarn: function(warning) { + // Skip certain warnings + + // should intercept ... but doesn't in some rollup versions + if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; } + // intercepts in some rollup versions + if ( warning.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { return; } + + // console.warn everything else + console.warn( warning.message ); + }, + plugins: [ + nodeResolve({jsnext: true, module: true}), + // #docregion commonjs + commonjs({ + include: 'node_modules/rxjs/**', + }), + // #enddocregion commonjs + // #docregion uglify + uglify() + // #enddocregion uglify + ] +} +// #enddocregion config diff --git a/public/docs/_examples/inheritance/ts/tsconfig-aot.json b/public/docs/_examples/inheritance/ts/tsconfig-aot.json new file mode 100644 index 0000000000..06ebb479ce --- /dev/null +++ b/public/docs/_examples/inheritance/ts/tsconfig-aot.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + }, + + "files": [ + "app/app.module.ts", + "app/main-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "skipMetadataEmit" : true + } +}