@@ -10,6 +10,7 @@ import assert from 'node:assert';
1010import { randomUUID } from 'node:crypto' ;
1111import { join } from 'node:path' ;
1212import { pathToFileURL } from 'node:url' ;
13+ import { MessagePort } from 'node:worker_threads' ;
1314import { fileURLToPath } from 'url' ;
1415import { JavaScriptTransformer } from '../../../tools/esbuild/javascript-transformer' ;
1516
@@ -21,12 +22,14 @@ import { JavaScriptTransformer } from '../../../tools/esbuild/javascript-transfo
2122const MEMORY_URL_SCHEME = 'memory://' ;
2223
2324export interface ESMInMemoryFileLoaderWorkerData {
24- outputFiles : Record < string , string > ;
25+ jsOutputFilesForWorker : Record < string , string > ;
2526 workspaceRoot : string ;
2627}
2728
28- let memoryVirtualRootUrl : string ;
29- let outputFiles : Record < string , string > ;
29+ interface ESMInMemoryFileLoaderResolutionData {
30+ memoryVirtualRootUrl : string ;
31+ outputFiles : Record < string , string > ;
32+ }
3033
3134const javascriptTransformer = new JavaScriptTransformer (
3235 // Always enable JIT linking to support applications built with and without AOT.
@@ -36,23 +39,46 @@ const javascriptTransformer = new JavaScriptTransformer(
3639 1 ,
3740) ;
3841
39- export function initialize ( data : ESMInMemoryFileLoaderWorkerData ) {
40- // This path does not actually exist but is used to overlay the in memory files with the
41- // actual filesystem for resolution purposes.
42- // A custom URL schema (such as `memory://`) cannot be used for the resolve output because
43- // the in-memory files may use `import.meta.url` in ways that assume a file URL.
44- // `createRequire` is one example of this usage.
45- memoryVirtualRootUrl = pathToFileURL (
46- join ( data . workspaceRoot , `.angular/prerender-root/${ randomUUID ( ) } /` ) ,
47- ) . href ;
48- outputFiles = data . outputFiles ;
42+ let resolveData : Promise < ESMInMemoryFileLoaderResolutionData > ;
43+
44+ export function initialize ( data : { port : MessagePort } | ESMInMemoryFileLoaderWorkerData ) {
45+ resolveData = new Promise < ESMInMemoryFileLoaderResolutionData > ( ( resolve ) => {
46+ if ( ! ( 'port' in data ) ) {
47+ /** TODO: Remove when Node.js Removes < 22.2 are no longer supported. */
48+ resolve ( {
49+ outputFiles : data . jsOutputFilesForWorker ,
50+ memoryVirtualRootUrl : pathToFileURL (
51+ join ( data . workspaceRoot , `.angular/prerender-root/${ randomUUID ( ) } /` ) ,
52+ ) . href ,
53+ } ) ;
54+
55+ return ;
56+ }
57+
58+ const { port } = data ;
59+ port . once (
60+ 'message' ,
61+ ( { jsOutputFilesForWorker, workspaceRoot } : ESMInMemoryFileLoaderWorkerData ) => {
62+ resolve ( {
63+ outputFiles : jsOutputFilesForWorker ,
64+ memoryVirtualRootUrl : pathToFileURL (
65+ join ( workspaceRoot , `.angular/prerender-root/${ randomUUID ( ) } /` ) ,
66+ ) . href ,
67+ } ) ;
68+
69+ port . close ( ) ;
70+ } ,
71+ ) ;
72+ } ) ;
4973}
5074
51- export function resolve (
75+ export async function resolve (
5276 specifier : string ,
5377 context : { parentURL : undefined | string } ,
5478 nextResolve : Function ,
5579) {
80+ const { outputFiles, memoryVirtualRootUrl } = await resolveData ;
81+
5682 // In-memory files loaded from external code will contain a memory scheme
5783 if ( specifier . startsWith ( MEMORY_URL_SCHEME ) ) {
5884 let memoryUrl ;
@@ -89,7 +115,7 @@ export function resolve(
89115
90116 if (
91117 specifierUrl ?. pathname &&
92- Object . hasOwn ( outputFiles , specifierUrl . href . slice ( memoryVirtualRootUrl . length ) )
118+ outputFiles [ specifierUrl . href . slice ( memoryVirtualRootUrl . length ) ] !== undefined
93119 ) {
94120 return {
95121 format : 'module' ,
@@ -114,6 +140,7 @@ export function resolve(
114140}
115141
116142export async function load ( url : string , context : { format ?: string | null } , nextLoad : Function ) {
143+ const { outputFiles, memoryVirtualRootUrl } = await resolveData ;
117144 const { format } = context ;
118145
119146 // Load the file from memory if the URL is based in the virtual root
0 commit comments