@@ -231,7 +231,7 @@ export function createServerMainCodeBundleOptions(
231231 target : string [ ] ,
232232 sourceFileCache : SourceFileCache ,
233233 stylesheetBundler : ComponentStylesheetBundler ,
234- ) : BuildOptions {
234+ ) : BundlerOptionsFactory {
235235 const {
236236 serverEntryPoint : mainServerEntryPoint ,
237237 workspaceRoot,
@@ -246,127 +246,129 @@ export function createServerMainCodeBundleOptions(
246246 'createServerCodeBundleOptions should not be called without a defined serverEntryPoint.' ,
247247 ) ;
248248
249- const pluginOptions = createCompilerPluginOptions ( options , sourceFileCache ) ;
250-
251- const mainServerNamespace = 'angular:main-server' ;
252- const mainServerInjectPolyfillsNamespace = 'angular:main-server-inject-polyfills' ;
253- const mainServerInjectManifestNamespace = 'angular:main-server-inject-manifest' ;
254- const zoneless = isZonelessApp ( polyfills ) ;
255- const entryPoints : Record < string , string > = {
256- 'main.server' : mainServerNamespace ,
257- } ;
249+ return ( loadResultCache ) => {
250+ const pluginOptions = createCompilerPluginOptions ( options , sourceFileCache , loadResultCache ) ;
258251
259- const ssrEntryPoint = ssrOptions ?. entry ;
260- const isOldBehaviour = ! outputMode ;
252+ const mainServerNamespace = 'angular:main-server' ;
253+ const mainServerInjectPolyfillsNamespace = 'angular:main-server-inject-polyfills' ;
254+ const mainServerInjectManifestNamespace = 'angular:main-server-inject-manifest' ;
255+ const zoneless = isZonelessApp ( polyfills ) ;
256+ const entryPoints : Record < string , string > = {
257+ 'main.server' : mainServerNamespace ,
258+ } ;
261259
262- if ( ssrEntryPoint && isOldBehaviour ) {
263- // Old behavior: 'server.ts' was bundled together with the SSR (Server-Side Rendering) code.
264- // This approach combined server-side logic and rendering into a single bundle.
265- entryPoints [ 'server' ] = ssrEntryPoint ;
266- }
260+ const ssrEntryPoint = ssrOptions ?. entry ;
261+ const isOldBehaviour = ! outputMode ;
267262
268- const buildOptions : BuildOptions = {
269- ...getEsBuildServerCommonOptions ( options ) ,
270- target,
271- inject : [ mainServerInjectPolyfillsNamespace , mainServerInjectManifestNamespace ] ,
272- entryPoints,
273- supported : getFeatureSupport ( target , zoneless ) ,
274- plugins : [
275- createWasmPlugin ( { allowAsync : zoneless , cache : sourceFileCache ?. loadResultCache } ) ,
276- createSourcemapIgnorelistPlugin ( ) ,
277- createCompilerPlugin (
278- // JS/TS options
279- { ...pluginOptions , noopTypeScriptCompilation : true } ,
280- // Component stylesheet bundler
281- stylesheetBundler ,
282- ) ,
283- ] ,
284- } ;
263+ if ( ssrEntryPoint && isOldBehaviour ) {
264+ // Old behavior: 'server.ts' was bundled together with the SSR (Server-Side Rendering) code.
265+ // This approach combined server-side logic and rendering into a single bundle.
266+ entryPoints [ 'server' ] = ssrEntryPoint ;
267+ }
285268
286- buildOptions . plugins ??= [ ] ;
269+ const buildOptions : BuildOptions = {
270+ ...getEsBuildServerCommonOptions ( options ) ,
271+ target,
272+ inject : [ mainServerInjectPolyfillsNamespace , mainServerInjectManifestNamespace ] ,
273+ entryPoints,
274+ supported : getFeatureSupport ( target , zoneless ) ,
275+ plugins : [
276+ createWasmPlugin ( { allowAsync : zoneless , cache : loadResultCache } ) ,
277+ createSourcemapIgnorelistPlugin ( ) ,
278+ createCompilerPlugin (
279+ // JS/TS options
280+ { ...pluginOptions , noopTypeScriptCompilation : true } ,
281+ // Component stylesheet bundler
282+ stylesheetBundler ,
283+ ) ,
284+ ] ,
285+ } ;
287286
288- if ( externalPackages ) {
289- buildOptions . packages = 'external' ;
290- } else {
291- buildOptions . plugins . push ( createRxjsEsmResolutionPlugin ( ) ) ;
292- }
287+ buildOptions . plugins ??= [ ] ;
293288
294- // Mark manifest and polyfills file as external as these are generated by a different bundle step.
295- ( buildOptions . external ??= [ ] ) . push ( ...SERVER_GENERATED_EXTERNALS ) ;
296- const isNodePlatform = options . ssrOptions ?. platform !== ExperimentalPlatform . Neutral ;
289+ if ( externalPackages ) {
290+ buildOptions . packages = 'external' ;
291+ } else {
292+ buildOptions . plugins . push ( createRxjsEsmResolutionPlugin ( ) ) ;
293+ }
297294
298- if ( ! isNodePlatform ) {
299- // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
300- // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
301- // Note: The framework already issues a warning when using XHR with SSR.
302- buildOptions . external . push ( 'xhr2' ) ;
303- }
295+ // Mark manifest and polyfills file as external as these are generated by a different bundle step.
296+ ( buildOptions . external ??= [ ] ) . push ( ...SERVER_GENERATED_EXTERNALS ) ;
297+ const isNodePlatform = options . ssrOptions ?. platform !== ExperimentalPlatform . Neutral ;
304298
305- buildOptions . plugins . push (
306- createServerBundleMetadata ( ) ,
307- createVirtualModulePlugin ( {
308- namespace : mainServerInjectPolyfillsNamespace ,
309- cache : sourceFileCache ?. loadResultCache ,
310- loadContent : ( ) => ( {
311- contents : `import './polyfills.server.mjs';` ,
312- loader : 'js' ,
313- resolveDir : workspaceRoot ,
314- } ) ,
315- } ) ,
316- createVirtualModulePlugin ( {
317- namespace : mainServerInjectManifestNamespace ,
318- cache : sourceFileCache ?. loadResultCache ,
319- loadContent : async ( ) => {
320- const contents : string [ ] = [
321- // Configure `@angular/ssr` manifest.
322- `import manifest from './${ SERVER_APP_MANIFEST_FILENAME } ';` ,
323- `import { ɵsetAngularAppManifest } from '@angular/ssr';` ,
324- `ɵsetAngularAppManifest(manifest);` ,
325- ] ;
299+ if ( ! isNodePlatform ) {
300+ // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
301+ // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
302+ // Note: The framework already issues a warning when using XHR with SSR.
303+ buildOptions . external . push ( 'xhr2' ) ;
304+ }
326305
327- return {
328- contents : contents . join ( '\n' ) ,
306+ buildOptions . plugins . push (
307+ createServerBundleMetadata ( ) ,
308+ createVirtualModulePlugin ( {
309+ namespace : mainServerInjectPolyfillsNamespace ,
310+ cache : loadResultCache ,
311+ loadContent : ( ) => ( {
312+ contents : `import './polyfills.server.mjs';` ,
329313 loader : 'js' ,
330314 resolveDir : workspaceRoot ,
331- } ;
332- } ,
333- } ) ,
334- createVirtualModulePlugin ( {
335- namespace : mainServerNamespace ,
336- cache : sourceFileCache ?. loadResultCache ,
337- loadContent : async ( ) => {
338- const mainServerEntryPointJsImport = entryFileToWorkspaceRelative (
339- workspaceRoot ,
340- mainServerEntryPoint ,
341- ) ;
315+ } ) ,
316+ } ) ,
317+ createVirtualModulePlugin ( {
318+ namespace : mainServerInjectManifestNamespace ,
319+ cache : loadResultCache ,
320+ loadContent : async ( ) => {
321+ const contents : string [ ] = [
322+ // Configure `@angular/ssr` manifest.
323+ `import manifest from './${ SERVER_APP_MANIFEST_FILENAME } ';` ,
324+ `import { ɵsetAngularAppManifest } from '@angular/ssr';` ,
325+ `ɵsetAngularAppManifest(manifest);` ,
326+ ] ;
327+
328+ return {
329+ contents : contents . join ( '\n' ) ,
330+ loader : 'js' ,
331+ resolveDir : workspaceRoot ,
332+ } ;
333+ } ,
334+ } ) ,
335+ createVirtualModulePlugin ( {
336+ namespace : mainServerNamespace ,
337+ cache : loadResultCache ,
338+ loadContent : async ( ) => {
339+ const mainServerEntryPointJsImport = entryFileToWorkspaceRelative (
340+ workspaceRoot ,
341+ mainServerEntryPoint ,
342+ ) ;
342343
343- const contents : string [ ] = [
344- // Re-export all symbols including default export from 'main.server.ts'
345- `export { default } from '${ mainServerEntryPointJsImport } ';` ,
346- `export * from '${ mainServerEntryPointJsImport } ';` ,
344+ const contents : string [ ] = [
345+ // Re-export all symbols including default export from 'main.server.ts'
346+ `export { default } from '${ mainServerEntryPointJsImport } ';` ,
347+ `export * from '${ mainServerEntryPointJsImport } ';` ,
347348
348- // Add @angular /ssr exports
349- `export {
349+ // Add @angular /ssr exports
350+ `export {
350351 ɵdestroyAngularServerApp,
351352 ɵextractRoutesAndCreateRouteTree,
352353 ɵgetOrCreateAngularServerApp,
353354 } from '@angular/ssr';` ,
354- ] ;
355+ ] ;
355356
356- return {
357- contents : contents . join ( '\n' ) ,
358- loader : 'js' ,
359- resolveDir : workspaceRoot ,
360- } ;
361- } ,
362- } ) ,
363- ) ;
357+ return {
358+ contents : contents . join ( '\n' ) ,
359+ loader : 'js' ,
360+ resolveDir : workspaceRoot ,
361+ } ;
362+ } ,
363+ } ) ,
364+ ) ;
364365
365- if ( options . plugins ) {
366- buildOptions . plugins . push ( ...options . plugins ) ;
367- }
366+ if ( options . plugins ) {
367+ buildOptions . plugins . push ( ...options . plugins ) ;
368+ }
368369
369- return buildOptions ;
370+ return buildOptions ;
371+ } ;
370372}
371373
372374export function createSsrEntryCodeBundleOptions (
0 commit comments