@@ -15,6 +15,7 @@ import {
15
15
import { JsonObject } from '@angular-devkit/core' ;
16
16
import * as fs from 'fs' ;
17
17
import * as path from 'path' ;
18
+ import Piscina from 'piscina' ;
18
19
import { normalizeOptimization } from '../../utils' ;
19
20
import { assertIsError } from '../../utils/error' ;
20
21
import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css' ;
@@ -42,10 +43,9 @@ async function _renderUniversal(
42
43
browserBuilderName ,
43
44
) ;
44
45
45
- // Initialize zone.js
46
+ // Locate zone.js to load in the render worker
46
47
const root = context . workspaceRoot ;
47
48
const zonePackage = require . resolve ( 'zone.js' , { paths : [ root ] } ) ;
48
- await import ( zonePackage ) ;
49
49
50
50
const projectName = context . target && context . target . project ;
51
51
if ( ! projectName ) {
@@ -63,65 +63,63 @@ async function _renderUniversal(
63
63
} )
64
64
: undefined ;
65
65
66
- for ( const { path : outputPath , baseHref } of browserResult . outputs ) {
67
- const localeDirectory = path . relative ( browserResult . baseOutputPath , outputPath ) ;
68
- const browserIndexOutputPath = path . join ( outputPath , 'index.html' ) ;
69
- const indexHtml = await fs . promises . readFile ( browserIndexOutputPath , 'utf8' ) ;
70
- const serverBundlePath = await _getServerModuleBundlePath (
71
- options ,
72
- context ,
73
- serverResult ,
74
- localeDirectory ,
75
- ) ;
76
-
77
- const { AppServerModule, renderModule } = await import ( serverBundlePath ) ;
78
-
79
- const renderModuleFn : ( ( module : unknown , options : { } ) => Promise < string > ) | undefined =
80
- renderModule ;
81
-
82
- if ( ! ( renderModuleFn && AppServerModule ) ) {
83
- throw new Error (
84
- `renderModule method and/or AppServerModule were not exported from: ${ serverBundlePath } .` ,
66
+ const renderWorker = new Piscina ( {
67
+ filename : require . resolve ( './render-worker' ) ,
68
+ maxThreads : 1 ,
69
+ workerData : { zonePackage } ,
70
+ } ) ;
71
+
72
+ try {
73
+ for ( const { path : outputPath , baseHref } of browserResult . outputs ) {
74
+ const localeDirectory = path . relative ( browserResult . baseOutputPath , outputPath ) ;
75
+ const browserIndexOutputPath = path . join ( outputPath , 'index.html' ) ;
76
+ const indexHtml = await fs . promises . readFile ( browserIndexOutputPath , 'utf8' ) ;
77
+ const serverBundlePath = await _getServerModuleBundlePath (
78
+ options ,
79
+ context ,
80
+ serverResult ,
81
+ localeDirectory ,
85
82
) ;
86
- }
87
83
88
- // Load platform server module renderer
89
- const renderOpts = {
90
- document : indexHtml ,
91
- url : options . route ,
92
- } ;
93
-
94
- let html = await renderModuleFn ( AppServerModule , renderOpts ) ;
95
- // Overwrite the client index file.
96
- const outputIndexPath = options . outputIndexPath
97
- ? path . join ( root , options . outputIndexPath )
98
- : browserIndexOutputPath ;
99
-
100
- if ( inlineCriticalCssProcessor ) {
101
- const { content, warnings, errors } = await inlineCriticalCssProcessor . process ( html , {
102
- outputPath,
84
+ let html : string = await renderWorker . run ( {
85
+ serverBundlePath,
86
+ document : indexHtml ,
87
+ url : options . route ,
103
88
} ) ;
104
- html = content ;
105
89
106
- if ( warnings . length || errors . length ) {
107
- spinner . stop ( ) ;
108
- warnings . forEach ( ( m ) => context . logger . warn ( m ) ) ;
109
- errors . forEach ( ( m ) => context . logger . error ( m ) ) ;
110
- spinner . start ( ) ;
90
+ // Overwrite the client index file.
91
+ const outputIndexPath = options . outputIndexPath
92
+ ? path . join ( root , options . outputIndexPath )
93
+ : browserIndexOutputPath ;
94
+
95
+ if ( inlineCriticalCssProcessor ) {
96
+ const { content, warnings, errors } = await inlineCriticalCssProcessor . process ( html , {
97
+ outputPath,
98
+ } ) ;
99
+ html = content ;
100
+
101
+ if ( warnings . length || errors . length ) {
102
+ spinner . stop ( ) ;
103
+ warnings . forEach ( ( m ) => context . logger . warn ( m ) ) ;
104
+ errors . forEach ( ( m ) => context . logger . error ( m ) ) ;
105
+ spinner . start ( ) ;
106
+ }
111
107
}
112
- }
113
108
114
- await fs . promises . writeFile ( outputIndexPath , html ) ;
109
+ await fs . promises . writeFile ( outputIndexPath , html ) ;
115
110
116
- if ( browserOptions . serviceWorker ) {
117
- await augmentAppWithServiceWorker (
118
- projectRoot ,
119
- root ,
120
- outputPath ,
121
- baseHref ?? '/' ,
122
- browserOptions . ngswConfigPath ,
123
- ) ;
111
+ if ( browserOptions . serviceWorker ) {
112
+ await augmentAppWithServiceWorker (
113
+ projectRoot ,
114
+ root ,
115
+ outputPath ,
116
+ baseHref ?? '/' ,
117
+ browserOptions . ngswConfigPath ,
118
+ ) ;
119
+ }
124
120
}
121
+ } finally {
122
+ await renderWorker . destroy ( ) ;
125
123
}
126
124
127
125
return browserResult ;
0 commit comments