ng2 2.0, Universal 2.0, TS 2.0, Preboot 4.*

This commit is contained in:
Mark Pieszak
2016-09-19 09:12:03 +01:00
committed by SteveSandersonMS
parent b71d139eb5
commit ce0d2089d2
18 changed files with 273 additions and 1166 deletions

View File

@@ -1,21 +1,30 @@
// the polyfills must be the first thing imported
import 'angular2-universal-polyfills';
import 'es6-shim';
require('zone.js');
import 'bootstrap';
import 'reflect-metadata';
import './styles/site.css';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { FormBuilder } from '@angular/common';
import { provideRouter } from '@angular/router';
import { HTTP_PROVIDERS } from '@angular/http';
import { App } from './components/app/app';
import { routes } from './routes';
// Angular 2
import { enableProdMode} from '@angular/core';
import { platformUniversalDynamic } from 'angular2-universal';
// enable prod for faster renders
enableProdMode();
import { MainModule } from './main.browser';
const platformRef = platformUniversalDynamic();
// on document ready bootstrap Angular 2
document.addEventListener('DOMContentLoaded', () => {
platformRef.bootstrapModule(MainModule);
});
bootstrap(App, [
...HTTP_PROVIDERS,
FormBuilder,
provideRouter(routes)
]);
// Basic hot reloading support. Automatically reloads and restarts the Angular 2 app each time
// you modify source files. This will not preserve any application state other than the URL.

View File

@@ -1,36 +1,76 @@
import 'angular2-universal/polyfills';
import * as ngCore from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { provideRouter } from '@angular/router';
import * as ngUniversal from 'angular2-universal';
import { BASE_URL, ORIGIN_URL, REQUEST_URL } from 'angular2-universal/common';
import { App } from './components/app/app';
// the polyfills must be the first thing imported in node.js
import 'angular2-universal-polyfills';
// Angular 2
import { enableProdMode } from '@angular/core';
// Angular2 Universal
import { platformNodeDynamic } from 'angular2-universal';
// Application imports
import { MainModule } from './main.node';
import { App } from './components';
import { routes } from './routes';
const bootloader = ngUniversal.bootloader({
async: true,
preboot: false,
platformProviders: [
ngCore.provide(APP_BASE_HREF, { useValue: '/' }),
]
});
// enable prod for faster renders
enableProdMode();
export default function (params: any): Promise<{ html: string, globals?: any }> {
const config: ngUniversal.AppConfig = {
directives: [App],
providers: [
ngCore.provide(ORIGIN_URL, { useValue: params.origin }),
ngCore.provide(REQUEST_URL, { useValue: params.url }),
...ngUniversal.NODE_HTTP_PROVIDERS,
provideRouter(routes),
...ngUniversal.NODE_LOCATION_PROVIDERS,
],
// TODO: Render just the <app> component instead of wrapping it inside an extra HTML document
// Waiting on https://github.com/angular/universal/issues/347
template: '<!DOCTYPE html>\n<html><head></head><body><app></app></body></html>'
declare var Zone: any;
export default function (params: any) : Promise<{ html: string, globals?: any }> {
const doc = `
<!DOCTYPE html>\n
<html>
<head></head>
<body>
<app></app>
</body>
</html>
`;
// hold platform reference
var platformRef = platformNodeDynamic();
var platformConfig = {
ngModule: MainModule,
document: doc,
preboot: false,
baseUrl: '/',
requestUrl: params.url,
originUrl: params.origin
};
return bootloader.serializeApplication(config).then(html => {
return { html };
// defaults
var cancel = false;
const _config = Object.assign({
get cancel() { return cancel; },
cancelHandler() { return Zone.current.get('cancel') }
}, platformConfig);
// for each user
const zone = Zone.current.fork({
name: 'UNIVERSAL request',
properties: _config
});
return Promise.resolve(
zone.run(() => {
return platformRef.serializeModule(Zone.current.get('ngModule'))
})
).then(html => {
if (typeof html !== 'string' ) {
return { html : doc };
}
return { html };
}).catch(err => {
console.log(err);
return { html : doc };
});
}

View File

@@ -1,11 +1,9 @@
import * as ng from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { Component } from '@angular/core';
import { NavMenu } from '../nav-menu/nav-menu';
@ng.Component({
@Component({
selector: 'app',
template: require('./app.html'),
directives: [...ROUTER_DIRECTIVES, NavMenu]
template: require('./app.html')
})
export class App {
}

View File

@@ -1,6 +1,6 @@
import * as ng from '@angular/core';
import { Component } from '@angular/core';
@ng.Component({
@Component({
selector: 'counter',
template: require('./counter.html')
})

View File

@@ -1,7 +1,7 @@
import * as ng from '@angular/core';
import { Component } from '@angular/core';
import { Http } from '@angular/http';
@ng.Component({
@Component({
selector: 'fetch-data',
template: require('./fetch-data.html')
})

View File

@@ -1,6 +1,6 @@
import * as ng from '@angular/core';
import { Component }from '@angular/core';
@ng.Component({
@Component({
selector: 'home',
template: require('./home.html')
})

View File

@@ -0,0 +1,8 @@
// Here we can create "Barrels" so that it's easier to import everything
// within /components
export * from './app/app';
export * from './counter/counter';
export * from './fetch-data/fetch-data';
export * from './home/home';
export * from './nav-menu/nav-menu';

View File

@@ -1,10 +1,8 @@
import * as ng from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { Component } from '@angular/core';
@ng.Component({
@Component({
selector: 'nav-menu',
template: require('./nav-menu.html'),
directives: [...ROUTER_DIRECTIVES]
template: require('./nav-menu.html')
})
export class NavMenu {
}

View File

@@ -0,0 +1,55 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { UniversalModule } from 'angular2-universal';
import {
App,
Counter,
FetchData,
Home,
NavMenu
} from './components';
import { routes } from './routes';
/* NOTE :
This file and `main.node.ts` are identical, at the moment(!)
By splitting these, you're able to create logic, imports, etc
that are "Platform" specific.
If you want your code to be completely Universal and don't need that
You can also just have 1 file, that is imported into both
* boot-client
* boot-server
*/
// ** Top-level NgModule "container" **
@NgModule({
// Root App Component
bootstrap: [ App ],
// Our Components
declarations: [
App, Counter, FetchData, Home, NavMenu
],
imports: [
// * NOTE: Needs to be your first import (!)
UniversalModule,
// * ^ BrowserModule, HttpModule, and JsonpModule are included here
// Your other imports can go here :
FormsModule,
// App Routing
RouterModule.forRoot(routes)
]
})
export class MainModule {
}

View File

@@ -0,0 +1,55 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { UniversalModule } from 'angular2-universal';
import {
App,
Counter,
FetchData,
Home,
NavMenu
} from './components';
import { routes } from './routes';
/* NOTE :
This file and `main.browser.ts` are identical, at the moment(!)
By splitting these, you're able to create logic, imports, etc
that are "Platform" specific.
If you want your code to be completely Universal and don't need that
You can also just have 1 file, that is imported into both
* boot-client
* boot-server
*/
// ** Top-level NgModule "container" **
@NgModule({
// Root App Component
bootstrap: [ App ],
// Our Components
declarations: [
App, Counter, FetchData, Home, NavMenu
],
imports: [
// * NOTE: Needs to be your first import (!)
UniversalModule,
// ^ NodeModule, NodeHttpModule, NodeJsonpModule are included for server
// Your other imports can go here:
FormsModule,
// App Routing
RouterModule.forRoot(routes)
]
})
export class MainModule {
}

View File

@@ -1,9 +1,8 @@
import { RouterConfig } from '@angular/router';
import { Home } from './components/home/home';
import { FetchData } from './components/fetch-data/fetch-data';
import { Counter } from './components/counter/counter';
import { Routes } from '@angular/router';
export const routes: RouterConfig = [
import { Home, FetchData, Counter } from './components';
export const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: Home },
{ path: 'counter', component: Counter },