@@ -11,7 +11,7 @@ import {
11
11
createBuilder ,
12
12
targetFromTargetString ,
13
13
} from '@angular-devkit/architect' ;
14
- import { JsonObject , join , normalize , resolve , schema } from '@angular-devkit/core' ;
14
+ import { JsonObject , join , normalize , resolve } from '@angular-devkit/core' ;
15
15
import { NodeJsSyncHost } from '@angular-devkit/core/node' ;
16
16
import * as fs from 'fs' ;
17
17
import * as path from 'path' ;
@@ -27,11 +27,6 @@ async function _renderUniversal(
27
27
browserResult : BrowserBuilderOutput ,
28
28
serverResult : ServerBuilderOutput ,
29
29
) : Promise < BrowserBuilderOutput > {
30
- const browserIndexOutputPath = path . join ( browserResult . outputPath || '' , 'index.html' ) ;
31
- const indexHtml = fs . readFileSync ( browserIndexOutputPath , 'utf8' ) ;
32
- const serverBundlePath = await _getServerModuleBundlePath ( options , context , serverResult ) ;
33
- const root = context . workspaceRoot ;
34
-
35
30
// Get browser target options.
36
31
const browserTarget = targetFromTargetString ( options . browserTarget ) ;
37
32
const rawBrowserOptions = await context . getTargetOptions ( browserTarget ) ;
@@ -42,65 +37,72 @@ async function _renderUniversal(
42
37
) ;
43
38
44
39
// Initialize zone.js
40
+ const root = context . workspaceRoot ;
45
41
const zonePackage = require . resolve ( 'zone.js' , { paths : [ root ] } ) ;
46
42
await import ( zonePackage ) ;
47
43
48
- const {
49
- AppServerModule,
50
- AppServerModuleNgFactory,
51
- renderModule,
52
- renderModuleFactory,
53
- } = await import ( serverBundlePath ) ;
54
-
55
- let renderModuleFn : ( module : unknown , options : { } ) => Promise < string > ;
56
- let AppServerModuleDef : unknown ;
57
-
58
- if ( renderModuleFactory && AppServerModuleNgFactory ) {
59
- renderModuleFn = renderModuleFactory ;
60
- AppServerModuleDef = AppServerModuleNgFactory ;
61
- } else if ( renderModule && AppServerModule ) {
62
- renderModuleFn = renderModule ;
63
- AppServerModuleDef = AppServerModule ;
64
- } else {
65
- throw new Error ( `renderModule method and/or AppServerModule were not exported from: ${ serverBundlePath } .` ) ;
44
+ const host = new NodeJsSyncHost ( ) ;
45
+ const projectName = context . target && context . target . project ;
46
+ if ( ! projectName ) {
47
+ throw new Error ( 'The builder requires a target.' ) ;
66
48
}
67
49
68
- // Load platform server module renderer
69
- const renderOpts = {
70
- document : indexHtml ,
71
- url : options . route ,
72
- } ;
73
-
74
- const html = await renderModuleFn ( AppServerModuleDef , renderOpts ) ;
75
- // Overwrite the client index file.
76
- const outputIndexPath = options . outputIndexPath
77
- ? path . join ( root , options . outputIndexPath )
78
- : browserIndexOutputPath ;
79
-
80
- fs . writeFileSync ( outputIndexPath , html ) ;
81
-
82
- if ( browserOptions . serviceWorker ) {
83
- const host = new NodeJsSyncHost ( ) ;
50
+ const projectMetadata = await context . getProjectMetadata ( projectName ) ;
51
+ const projectRoot = resolve (
52
+ normalize ( root ) ,
53
+ normalize ( ( projectMetadata . root as string ) || '' ) ,
54
+ ) ;
84
55
85
- const projectName = context . target && context . target . project ;
86
- if ( ! projectName ) {
87
- throw new Error ( 'The builder requires a target.' ) ;
56
+ for ( const outputPath of browserResult . outputPaths ) {
57
+ const localeDirectory = path . relative ( browserResult . baseOutputPath , outputPath ) ;
58
+ const browserIndexOutputPath = path . join ( outputPath , 'index.html' ) ;
59
+ const indexHtml = fs . readFileSync ( browserIndexOutputPath , 'utf8' ) ;
60
+ const serverBundlePath = await _getServerModuleBundlePath ( options , context , serverResult , localeDirectory ) ;
61
+
62
+ const {
63
+ AppServerModule,
64
+ AppServerModuleNgFactory,
65
+ renderModule,
66
+ renderModuleFactory,
67
+ } = await import ( serverBundlePath ) ;
68
+
69
+ let renderModuleFn : ( module : unknown , options : { } ) => Promise < string > ;
70
+ let AppServerModuleDef : unknown ;
71
+
72
+ if ( renderModuleFactory && AppServerModuleNgFactory ) {
73
+ renderModuleFn = renderModuleFactory ;
74
+ AppServerModuleDef = AppServerModuleNgFactory ;
75
+ } else if ( renderModule && AppServerModule ) {
76
+ renderModuleFn = renderModule ;
77
+ AppServerModuleDef = AppServerModule ;
78
+ } else {
79
+ throw new Error ( `renderModule method and/or AppServerModule were not exported from: ${ serverBundlePath } .` ) ;
88
80
}
89
81
90
- const projectMetadata = await context . getProjectMetadata ( projectName ) ;
91
- const projectRoot = resolve (
92
- normalize ( context . workspaceRoot ) ,
93
- normalize ( ( projectMetadata . root as string ) || '' ) ,
94
- ) ;
95
-
96
- await augmentAppWithServiceWorker (
97
- host ,
98
- normalize ( root ) ,
99
- projectRoot ,
100
- join ( normalize ( root ) , browserOptions . outputPath ) ,
101
- browserOptions . baseHref || '/' ,
102
- browserOptions . ngswConfigPath ,
103
- ) ;
82
+ // Load platform server module renderer
83
+ const renderOpts = {
84
+ document : indexHtml ,
85
+ url : options . route ,
86
+ } ;
87
+
88
+ const html = await renderModuleFn ( AppServerModuleDef , renderOpts ) ;
89
+ // Overwrite the client index file.
90
+ const outputIndexPath = options . outputIndexPath
91
+ ? path . join ( root , options . outputIndexPath )
92
+ : browserIndexOutputPath ;
93
+
94
+ fs . writeFileSync ( outputIndexPath , html ) ;
95
+
96
+ if ( browserOptions . serviceWorker ) {
97
+ await augmentAppWithServiceWorker (
98
+ host ,
99
+ normalize ( root ) ,
100
+ projectRoot ,
101
+ normalize ( outputPath ) ,
102
+ browserOptions . baseHref || '/' ,
103
+ browserOptions . ngswConfigPath ,
104
+ ) ;
105
+ }
104
106
}
105
107
106
108
return browserResult ;
@@ -110,11 +112,18 @@ async function _getServerModuleBundlePath(
110
112
options : BuildWebpackAppShellSchema ,
111
113
context : BuilderContext ,
112
114
serverResult : ServerBuilderOutput ,
115
+ browserLocaleDirectory : string ,
113
116
) {
114
117
if ( options . appModuleBundle ) {
115
118
return path . join ( context . workspaceRoot , options . appModuleBundle ) ;
116
119
} else {
117
- const outputPath = serverResult . outputPath || '/' ;
120
+ const { baseOutputPath = '' } = serverResult ;
121
+ const outputPath = path . join ( baseOutputPath , browserLocaleDirectory ) ;
122
+
123
+ if ( ! fs . existsSync ( outputPath ) ) {
124
+ throw new Error ( `Could not find server output directory: ${ outputPath } .` ) ;
125
+ }
126
+
118
127
const files = fs . readdirSync ( outputPath , 'utf8' ) ;
119
128
const re = / ^ m a i n \. (?: [ a - z A - Z 0 - 9 ] { 20 } \. ) ? (?: b u n d l e \. ) ? j s $ / ;
120
129
const maybeMain = files . filter ( x => re . test ( x ) ) [ 0 ] ;
@@ -140,15 +149,17 @@ async function _appShellBuilder(
140
149
watch : false ,
141
150
serviceWorker : false ,
142
151
} ) ;
143
- const serverTargetRun = await context . scheduleTarget ( serverTarget , { } ) ;
152
+ const serverTargetRun = await context . scheduleTarget ( serverTarget , {
153
+ watch : false ,
154
+ } ) ;
144
155
145
156
try {
146
157
const [ browserResult , serverResult ] = await Promise . all ( [
147
- ( browserTargetRun . result as { } ) as BrowserBuilderOutput ,
148
- serverTargetRun . result ,
158
+ browserTargetRun . result as unknown as BrowserBuilderOutput ,
159
+ serverTargetRun . result as unknown as ServerBuilderOutput ,
149
160
] ) ;
150
161
151
- if ( browserResult . success === false || browserResult . outputPath === undefined ) {
162
+ if ( browserResult . success === false || browserResult . baseOutputPath === undefined ) {
152
163
return browserResult ;
153
164
} else if ( serverResult . success === false ) {
154
165
return serverResult ;
0 commit comments