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 --> <!-- Include the newly-built files in the publish output -->
<ItemGroup> <ItemGroup>
<DistFiles Include="wwwroot\dist\**; $(SpaRoot)dist-server\**" /> <DistFiles Include="wwwroot\dist\**; $(SpaRoot)dist-server\**" />
<DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)"> <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath> <RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <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": { "@schematics/angular": {
"version": "0.1.3", "version": "0.1.3",
"dev": true "dev": true

View File

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

View File

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

View File

@ -1,38 +1,29 @@
import 'zone.js/dist/zone-node';
import 'reflect-metadata'; import 'reflect-metadata';
import 'zone.js'; import { renderModule, renderModuleFactory } from '@angular/platform-server';
import 'rxjs/add/operator/first';
import { APP_BASE_HREF } from '@angular/common'; import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode, ApplicationRef, NgModule, NgZone, ValueProvider } from '@angular/core'; import { enableProdMode } from '@angular/core';
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server'; import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { AppServerModule } from './app/app.server.module'; import { createServerRenderer } from 'aspnet-prerendering';
import { createServerRenderer, RenderResult } from 'aspnet-prerendering'; export { AppServerModule } from './app/app.server.module';
const { AppServerModule, AppServerModuleNgFactory, LAZY_MODULE_MAP } = (module as any).exports;
enableProdMode(); enableProdMode();
export default createServerRenderer(params => { export default createServerRenderer(params => {
const providers = [ const options = {
{ provide: INITIAL_CONFIG, useValue: { document: params.data.originalHtml, url: params.url } }, document: params.data.originalHtml,
{ provide: APP_BASE_HREF, useValue: params.baseUrl }, url: params.url,
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl }, 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 renderPromise = AppServerModuleNgFactory
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef); ? /* AoT */ renderModuleFactory(AppServerModuleNgFactory, options)
const state = moduleRef.injector.get(PlatformState); : /* dev */ renderModule(AppServerModule, options);
const zone: NgZone = moduleRef.injector.get(NgZone);
return new Promise<RenderResult>((resolve, reject) => { return renderPromise.then(html => ({ html }));
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();
});
});
});
});
}); });