@@ -13,25 +13,70 @@ import * as fs from 'fs';
13
13
import * as path from 'path' ;
14
14
15
15
import { Schema } from './schema' ;
16
+ import { getRoutes } from './utils' ;
16
17
17
18
export type PrerenderBuilderOptions = Schema & json . JsonObject ;
18
19
19
- export type PrerenderBuilderOutput = BuilderOutput & {
20
+ export type PrerenderBuilderOutput = BuilderOutput ;
21
+
22
+ type BuildBuilderOutput = BuilderOutput & {
20
23
baseOutputPath : string ;
21
24
outputPaths : string [ ] ;
22
25
outputPath : string ;
23
26
} ;
24
27
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
+
25
70
/**
26
71
* Renders each route in options.routes and writes them to
27
72
* <route>/index.html for each output path in the browser result.
28
73
*/
29
74
async function _renderUniversal (
30
- options : Schema ,
75
+ routes : string [ ] ,
31
76
context : BuilderContext ,
32
- browserResult : PrerenderBuilderOutput ,
33
- serverResult : PrerenderBuilderOutput ,
34
- ) : Promise < PrerenderBuilderOutput > {
77
+ browserResult : BuildBuilderOutput ,
78
+ serverResult : BuildBuilderOutput ,
79
+ ) : Promise < BuildBuilderOutput > {
35
80
// We need to render the routes for each locale from the browser output.
36
81
for ( const outputPath of browserResult . outputPaths ) {
37
82
const localeDirectory = path . relative ( browserResult . baseOutputPath , outputPath ) ;
@@ -40,10 +85,10 @@ async function _renderUniversal(
40
85
const { AppServerModuleDef, renderModuleFn } =
41
86
await _getServerModuleBundle ( serverResult , localeDirectory ) ;
42
87
43
- context . logger . info ( `\nPrerendering ${ options . routes . length } route(s) to ${ outputPath } ` ) ;
88
+ context . logger . info ( `\nPrerendering ${ routes . length } route(s) to ${ outputPath } ` ) ;
44
89
45
90
// Render each route and write them to <route>/index.html.
46
- for ( const route of options . routes ) {
91
+ for ( const route of routes ) {
47
92
const renderOpts = {
48
93
document : indexHtml + '<!-- This page was prerendered with Angular Universal -->' ,
49
94
url : route ,
@@ -59,8 +104,6 @@ async function _renderUniversal(
59
104
fs . writeFileSync ( browserIndexOutputPathOriginal , indexHtml ) ;
60
105
}
61
106
62
- // There will never conflicting output folders
63
- // because items in options.routes must be unique.
64
107
try {
65
108
fs . mkdirSync ( outputFolderPath , { recursive : true } ) ;
66
109
fs . writeFileSync ( outputIndexPath , html ) ;
@@ -84,7 +127,7 @@ async function _renderUniversal(
84
127
* Throws if no app module bundle is found.
85
128
*/
86
129
async function _getServerModuleBundle (
87
- serverResult : PrerenderBuilderOutput ,
130
+ serverResult : BuildBuilderOutput ,
88
131
browserLocaleDirectory : string ,
89
132
) {
90
133
const { baseOutputPath = '' } = serverResult ;
@@ -127,38 +170,18 @@ async function _getServerModuleBundle(
127
170
export async function execute (
128
171
options : PrerenderBuilderOptions ,
129
172
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 ;
161
182
}
183
+
184
+ return _renderUniversal ( routes , context , browserResult , serverResult ) ;
162
185
}
163
186
164
187
export default createBuilder ( execute ) ;
0 commit comments