Update to newer Angular SSR APIs to support AoT-enabled builds

This commit is contained in:
Steve Sanderson 2017-11-22 15:17:34 +00:00
parent dd8aef8699
commit 505ebcf1e6
5 changed files with 31 additions and 32 deletions

View File

@ -56,6 +56,7 @@
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="wwwroot\dist\**; $(SpaRoot)dist-server\**" />
<DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>

View File

@ -78,6 +78,11 @@
}
}
},
"@nguniversal/module-map-ngfactory-loader": {
"version": "5.0.0-beta.5",
"from": "@nguniversal/module-map-ngfactory-loader@latest",
"resolved": "https://registry.npmjs.org/@nguniversal/module-map-ngfactory-loader/-/module-map-ngfactory-loader-5.0.0-beta.5.tgz"
},
"@schematics/angular": {
"version": "0.1.3",
"dev": true

View File

@ -6,7 +6,7 @@
"ng": "ng",
"start": "ng serve --deploy-url=/dist/ --output-hashing=media --extract-css",
"build": "ng build --deploy-url=/dist/ --output-hashing=media --extract-css",
"build:ssr": "ng build --deploy-url=/dist/ --output-hashing=media --extract-css --bundle-dependencies=all --app=ssr",
"build:ssr": "ng build --deploy-url=/dist/ --output-hashing=media --extract-css --app=ssr",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
@ -23,6 +23,7 @@
"@angular/platform-browser-dynamic": "^5.0.0",
"@angular/platform-server": "^5.0.0",
"@angular/router": "^5.0.0",
"@nguniversal/module-map-ngfactory-loader": "^5.0.0-beta.5",
"aspnet-prerendering": "^3.0.1",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",

View File

@ -1,10 +1,11 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppComponent } from './app.component';
import { AppModule } from './app.module';
@NgModule({
imports: [AppModule, ServerModule],
imports: [AppModule, ServerModule, ModuleMapLoaderModule],
bootstrap: [AppComponent]
})
export class AppServerModule { }

View File

@ -1,38 +1,29 @@
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import 'zone.js';
import 'rxjs/add/operator/first';
import { renderModule, renderModuleFactory } from '@angular/platform-server';
import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode, ApplicationRef, NgModule, NgZone, ValueProvider } from '@angular/core';
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
import { AppServerModule } from './app/app.server.module';
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
import { enableProdMode } from '@angular/core';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { createServerRenderer } from 'aspnet-prerendering';
export { AppServerModule } from './app/app.server.module';
const { AppServerModule, AppServerModuleNgFactory, LAZY_MODULE_MAP } = (module as any).exports;
enableProdMode();
export default createServerRenderer(params => {
const providers = [
{ provide: INITIAL_CONFIG, useValue: { document: params.data.originalHtml, url: params.url } },
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
];
const options = {
document: params.data.originalHtml,
url: params.url,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl }
]
};
return platformDynamicServer(providers).bootstrapModule(AppServerModule).then(moduleRef => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
const state = moduleRef.injector.get(PlatformState);
const zone: NgZone = moduleRef.injector.get(NgZone);
return new Promise<RenderResult>((resolve, reject) => {
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
appRef.isStable.first(isStable => isStable).subscribe(() => {
// Because 'onStable' fires before 'onError', we have to delay slightly before
// completing the request in case there's an error to report
setImmediate(() => {
resolve({
html: state.renderToString()
});
moduleRef.destroy();
});
});
});
});
const renderPromise = AppServerModuleNgFactory
? /* AoT */ renderModuleFactory(AppServerModuleNgFactory, options)
: /* dev */ renderModule(AppServerModule, options);
return renderPromise.then(html => ({ html }));
});