@@ -15,6 +15,7 @@ import {
1515import { JsonObject } from '@angular-devkit/core' ;
1616import * as fs from 'fs' ;
1717import * as path from 'path' ;
18+ import Piscina from 'piscina' ;
1819import { normalizeOptimization } from '../../utils' ;
1920import { assertIsError } from '../../utils/error' ;
2021import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css' ;
@@ -42,10 +43,9 @@ async function _renderUniversal(
4243 browserBuilderName ,
4344 ) ;
4445
45- // Initialize zone.js
46+ // Locate zone.js to load in the render worker
4647 const root = context . workspaceRoot ;
4748 const zonePackage = require . resolve ( 'zone.js' , { paths : [ root ] } ) ;
48- await import ( zonePackage ) ;
4949
5050 const projectName = context . target && context . target . project ;
5151 if ( ! projectName ) {
@@ -63,65 +63,63 @@ async function _renderUniversal(
6363 } )
6464 : undefined ;
6565
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 ,
8582 ) ;
86- }
8783
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 ,
10388 } ) ;
104- html = content ;
10589
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+ }
111107 }
112- }
113108
114- await fs . promises . writeFile ( outputIndexPath , html ) ;
109+ await fs . promises . writeFile ( outputIndexPath , html ) ;
115110
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+ }
124120 }
121+ } finally {
122+ await renderWorker . destroy ( ) ;
125123 }
126124
127125 return browserResult ;
0 commit comments