@@ -13,25 +13,70 @@ import * as fs from 'fs';
1313import * as path from 'path' ;
1414
1515import { Schema } from './schema' ;
16+ import { getRoutes } from './utils' ;
1617
1718export type PrerenderBuilderOptions = Schema & json . JsonObject ;
1819
19- export type PrerenderBuilderOutput = BuilderOutput & {
20+ export type PrerenderBuilderOutput = BuilderOutput ;
21+
22+ type BuildBuilderOutput = BuilderOutput & {
2023 baseOutputPath : string ;
2124 outputPaths : string [ ] ;
2225 outputPath : string ;
2326} ;
2427
28+ type ScheduleBuildsOutput = BuilderOutput & {
29+ serverResult ?: BuildBuilderOutput ;
30+ browserResult ?: BuildBuilderOutput ;
31+ } ;
32+
33+ /**
34+ * Schedules the server and browser builds and returns their results if both builds are successful.
35+ */
36+ async function _scheduleBuilds (
37+ options : PrerenderBuilderOptions ,
38+ context : BuilderContext
39+ ) : Promise < ScheduleBuildsOutput > {
40+ const browserTarget = targetFromTargetString ( options . browserTarget ) ;
41+ const serverTarget = targetFromTargetString ( options . serverTarget ) ;
42+
43+ const browserTargetRun = await context . scheduleTarget ( browserTarget , {
44+ watch : false ,
45+ serviceWorker : false ,
46+ // todo: handle service worker augmentation
47+ } ) ;
48+ const serverTargetRun = await context . scheduleTarget ( serverTarget , {
49+ watch : false ,
50+ } ) ;
51+
52+ try {
53+ const [ browserResult , serverResult ] = await Promise . all ( [
54+ browserTargetRun . result as unknown as BuildBuilderOutput ,
55+ serverTargetRun . result as unknown as BuildBuilderOutput ,
56+ ] ) ;
57+
58+ const success =
59+ browserResult . success && serverResult . success && browserResult . baseOutputPath !== undefined ;
60+ const error = browserResult . error || serverResult . error as string ;
61+
62+ return { success, error, browserResult, serverResult } ;
63+ } catch ( e ) {
64+ return { success : false , error : e . message } ;
65+ } finally {
66+ await Promise . all ( [ browserTargetRun . stop ( ) , serverTargetRun . stop ( ) ] ) ;
67+ }
68+ }
69+
2570/**
2671 * Renders each route in options.routes and writes them to
2772 * <route>/index.html for each output path in the browser result.
2873 */
2974async function _renderUniversal (
30- options : Schema ,
75+ routes : string [ ] ,
3176 context : BuilderContext ,
32- browserResult : PrerenderBuilderOutput ,
33- serverResult : PrerenderBuilderOutput ,
34- ) : Promise < PrerenderBuilderOutput > {
77+ browserResult : BuildBuilderOutput ,
78+ serverResult : BuildBuilderOutput ,
79+ ) : Promise < BuildBuilderOutput > {
3580 // We need to render the routes for each locale from the browser output.
3681 for ( const outputPath of browserResult . outputPaths ) {
3782 const localeDirectory = path . relative ( browserResult . baseOutputPath , outputPath ) ;
@@ -40,10 +85,10 @@ async function _renderUniversal(
4085 const { AppServerModuleDef, renderModuleFn } =
4186 await _getServerModuleBundle ( serverResult , localeDirectory ) ;
4287
43- context . logger . info ( `\nPrerendering ${ options . routes . length } route(s) to ${ outputPath } ` ) ;
88+ context . logger . info ( `\nPrerendering ${ routes . length } route(s) to ${ outputPath } ` ) ;
4489
4590 // Render each route and write them to <route>/index.html.
46- for ( const route of options . routes ) {
91+ for ( const route of routes ) {
4792 const renderOpts = {
4893 document : indexHtml + '<!-- This page was prerendered with Angular Universal -->' ,
4994 url : route ,
@@ -59,8 +104,6 @@ async function _renderUniversal(
59104 fs . writeFileSync ( browserIndexOutputPathOriginal , indexHtml ) ;
60105 }
61106
62- // There will never conflicting output folders
63- // because items in options.routes must be unique.
64107 try {
65108 fs . mkdirSync ( outputFolderPath , { recursive : true } ) ;
66109 fs . writeFileSync ( outputIndexPath , html ) ;
@@ -84,7 +127,7 @@ async function _renderUniversal(
84127 * Throws if no app module bundle is found.
85128 */
86129async function _getServerModuleBundle (
87- serverResult : PrerenderBuilderOutput ,
130+ serverResult : BuildBuilderOutput ,
88131 browserLocaleDirectory : string ,
89132) {
90133 const { baseOutputPath = '' } = serverResult ;
@@ -127,38 +170,18 @@ async function _getServerModuleBundle(
127170export async function execute (
128171 options : PrerenderBuilderOptions ,
129172 context : BuilderContext
130- ) : Promise < PrerenderBuilderOutput | BuilderOutput > {
131- const browserTarget = targetFromTargetString ( options . browserTarget ) ;
132- const serverTarget = targetFromTargetString ( options . serverTarget ) ;
133-
134- const browserTargetRun = await context . scheduleTarget ( browserTarget , {
135- watch : false ,
136- serviceWorker : false ,
137- // todo: handle service worker augmentation
138- } ) ;
139- const serverTargetRun = await context . scheduleTarget ( serverTarget , {
140- watch : false ,
141- } ) ;
142-
143- try {
144- const [ browserResult , serverResult ] = await Promise . all ( [
145- browserTargetRun . result as unknown as PrerenderBuilderOutput ,
146- serverTargetRun . result as unknown as PrerenderBuilderOutput ,
147- ] ) ;
148-
149- if ( browserResult . success === false || browserResult . baseOutputPath === undefined ) {
150- return browserResult ;
151- }
152- if ( serverResult . success === false ) {
153- return serverResult ;
154- }
155-
156- return await _renderUniversal ( options , context , browserResult , serverResult ) ;
157- } catch ( e ) {
158- return { success : false , error : e . message } ;
159- } finally {
160- await Promise . all ( [ browserTargetRun . stop ( ) , serverTargetRun . stop ( ) ] ) ;
173+ ) : Promise < PrerenderBuilderOutput > {
174+ const routes = getRoutes ( context . workspaceRoot , options . routesFile , options . routes ) ;
175+ if ( ! routes . length ) {
176+ throw new Error ( 'No routes found.' ) ;
177+ }
178+ const result = await _scheduleBuilds ( options , context ) ;
179+ const { success, error, browserResult, serverResult } = result ;
180+ if ( ! success || ! browserResult || ! serverResult ) {
181+ return { success, error } as BuilderOutput ;
161182 }
183+
184+ return _renderUniversal ( routes , context , browserResult , serverResult ) ;
162185}
163186
164187export default createBuilder ( execute ) ;
0 commit comments