99import type { Metafile } from 'esbuild' ;
1010import { Buffer } from 'node:buffer' ;
1111import { extname } from 'node:path' ;
12- import { NormalizedApplicationBuildOptions } from '../../builders/application/options' ;
12+ import {
13+ INDEX_HTML_SERVER ,
14+ NormalizedApplicationBuildOptions ,
15+ } from '../../builders/application/options' ;
1316import {
1417 type BuildOutputFile ,
1518 BuildOutputFileType ,
1619 createOutputFile ,
1720} from '../../tools/esbuild/bundler-files' ;
21+ import { findNonce } from '../index-file/nonce' ;
22+ import { joinUrlParts } from '../url' ;
1823
1924export const SERVER_APP_MANIFEST_FILENAME = 'angular-app-manifest.mjs' ;
2025export const SERVER_APP_ENGINE_MANIFEST_FILENAME = 'angular-app-engine-manifest.mjs' ;
@@ -33,11 +38,6 @@ export const SERVER_GENERATED_EXTERNALS = new Set([
3338 './' + SERVER_APP_ENGINE_MANIFEST_FILENAME ,
3439] ) ;
3540
36- interface FilesMapping {
37- path : string ;
38- dynamicImport : boolean ;
39- }
40-
4141const MAIN_SERVER_OUTPUT_FILENAME = 'main.server.mjs' ;
4242
4343/**
@@ -143,7 +143,7 @@ export default {
143143 * - `manifestContent`: A string of the SSR manifest content.
144144 * - `serverAssetsChunks`: An array of build output files containing the generated assets for the server.
145145 */
146- export function generateAngularServerAppManifest (
146+ export async function generateAngularServerAppManifest (
147147 additionalHtmlOutputFiles : Map < string , BuildOutputFile > ,
148148 outputFiles : BuildOutputFile [ ] ,
149149 inlineCriticalCss : boolean ,
@@ -153,16 +153,23 @@ export function generateAngularServerAppManifest(
153153 initialFiles : Set < string > ,
154154 metafile : Metafile ,
155155 publicPath : string | undefined ,
156- ) : {
156+ ) : Promise < {
157157 manifestContent : string ;
158158 serverAssetsChunks : BuildOutputFile [ ] ;
159- } {
159+ } > {
160160 const serverAssetsChunks : BuildOutputFile [ ] = [ ] ;
161161 const serverAssets : Record < string , string > = { } ;
162+ const criticalCssPlans : unknown [ ] = [ ] ;
163+ let nonce : string | undefined ;
164+
165+ // TODO(alanagius): This is done here as we do not use module resolution bundler/node16
166+ const { compileSheet, encodePlan } = ( await import (
167+ 'beasties/compiler' as string
168+ ) ) as typeof import ( 'beasties/compiler' , { with : { 'resolution-mode' : 'import' } } ) ;
162169
163170 for ( const file of [ ...additionalHtmlOutputFiles . values ( ) , ...outputFiles ] ) {
164171 const extension = extname ( file . path ) ;
165- if ( extension === '.html' || ( inlineCriticalCss && extension === '.css' ) ) {
172+ if ( extension === '.html' ) {
166173 const jsChunkFilePath = `assets-chunks/${ file . path . replace ( / [ . / ] / g, '_' ) } .mjs` ;
167174 const escapedContent = escapeUnsafeChars ( file . text ) ;
168175
@@ -185,9 +192,19 @@ export function generateAngularServerAppManifest(
185192
186193 serverAssets [ file . path ] =
187194 `{size: ${ size } , hash: '${ file . hash } ', text: () => import('./${ jsChunkFilePath } ').then(m => m.default)}` ;
195+ } else if ( inlineCriticalCss && extension === '.css' ) {
196+ const sheet = compileSheet ( file . text , {
197+ href : joinUrlParts ( publicPath ?? '' , file . path ) ,
198+ } ) ;
199+ criticalCssPlans . push ( encodePlan ( sheet ) ) ;
188200 }
189201 }
190202
203+ const indexHtml = additionalHtmlOutputFiles . get ( INDEX_HTML_SERVER ) ?. text ;
204+ if ( indexHtml ) {
205+ nonce = ( await findNonce ( indexHtml ) ) ?? undefined ;
206+ }
207+
191208 // When routes have been extracted, mappings are no longer needed, as preloads will be included in the metadata.
192209 const entryPointToBrowserMapping = routes ?. length
193210 ? undefined
@@ -196,9 +213,10 @@ export function generateAngularServerAppManifest(
196213 const manifestContent = `
197214export default {
198215 bootstrap: () => import('./main.server.mjs').then(m => m.default),
199- inlineCriticalCss: ${ inlineCriticalCss } ,
200216 baseHref: '${ baseHref } ',
201- locale: ${ JSON . stringify ( locale ) } ,
217+ ${ criticalCssPlans . length ? ` criticalCssPlans: ${ JSON . stringify ( criticalCssPlans ) } ,\n` : '' } ${
218+ nonce ? ` nonce: ${ JSON . stringify ( nonce ) } ,\n` : ''
219+ } locale: ${ JSON . stringify ( locale ) } ,
202220 routes: ${ JSON . stringify ( routes , undefined , 2 ) } ,
203221 entryPointToBrowserMapping: ${ JSON . stringify ( entryPointToBrowserMapping , undefined , 2 ) } ,
204222 assets: {
0 commit comments