@@ -95,7 +95,8 @@ function loadChunk(chunkData: ChunkData, source?: SourceInfo): void {
95
95
const loadedChunks = new Set < ChunkPath > ( )
96
96
const unsupportedLoadChunk = Promise . resolve ( undefined )
97
97
const loadedChunk = Promise . resolve ( undefined )
98
- const chunkCache = new Map < ChunkPath , Promise < any > | null > ( )
98
+ // Holds either a rejected promise or `loadedChunk` for success
99
+ const chunkCache = new Map < ChunkPath , Promise < void > > ( )
99
100
100
101
function clearChunkCache ( ) {
101
102
chunkCache . clear ( )
@@ -143,47 +144,30 @@ function loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {
143
144
}
144
145
}
145
146
146
- async function loadChunkAsyncUncached (
147
- source : SourceInfo ,
148
- chunkPath : ChunkPath
149
- ) : Promise < void > {
147
+ function loadChunkUncached ( chunkPath : ChunkPath ) {
148
+ // resolve to an absolute path to simplify `require` handling
150
149
const resolved = path . resolve ( RUNTIME_ROOT , chunkPath )
151
150
152
- try {
153
- // use await to ensure that evaluation happens in another microtask
154
- // Because we are using a resolved absolute path require shouldn't waste time probing node_modules.
155
- const exports = await require ( resolved )
156
- const chunkModules : CompressedModuleFactories = exports
157
- for ( const [ moduleId , moduleFactory ] of Object . entries ( chunkModules ) ) {
158
- if ( ! moduleFactories [ moduleId ] ) {
159
- if ( Array . isArray ( moduleFactory ) ) {
160
- const [ moduleFactoryFn , otherIds ] = moduleFactory
161
- moduleFactories [ moduleId ] = moduleFactoryFn
162
- for ( const otherModuleId of otherIds ) {
163
- moduleFactories [ otherModuleId ] = moduleFactoryFn
164
- }
165
- } else {
166
- moduleFactories [ moduleId ] = moduleFactory
151
+ const chunkModules : CompressedModuleFactories = require ( resolved )
152
+ for ( const [ moduleId , moduleFactory ] of Object . entries ( chunkModules ) ) {
153
+ if ( ! moduleFactories [ moduleId ] ) {
154
+ if ( Array . isArray ( moduleFactory ) ) {
155
+ const [ moduleFactoryFn , otherIds ] = moduleFactory
156
+ moduleFactories [ moduleId ] = moduleFactoryFn
157
+ for ( const otherModuleId of otherIds ) {
158
+ moduleFactories [ otherModuleId ] = moduleFactoryFn
167
159
}
160
+ } else {
161
+ moduleFactories [ moduleId ] = moduleFactory
168
162
}
169
163
}
170
- } catch ( e ) {
171
- let errorMessage = `Failed to load chunk ${ chunkPath } `
172
-
173
- if ( source ) {
174
- errorMessage += ` from ${ stringifySourceInfo ( source ) } `
175
- }
176
-
177
- throw new Error ( errorMessage , {
178
- cause : e ,
179
- } )
180
164
}
181
165
}
182
166
183
167
function loadChunkAsync (
184
168
source : SourceInfo ,
185
169
chunkData : ChunkData
186
- ) : Promise < any > {
170
+ ) : Promise < void > {
187
171
const chunkPath = typeof chunkData === 'string' ? chunkData : chunkData . path
188
172
if ( ! isJs ( chunkPath ) ) {
189
173
// We only support loading JS chunks in Node.js.
@@ -193,14 +177,27 @@ function loadChunkAsync(
193
177
194
178
let entry = chunkCache . get ( chunkPath )
195
179
if ( entry === undefined ) {
196
- const resolve = chunkCache . set . bind ( chunkCache , chunkPath , null )
197
- // A new Promise ensures callers that don't handle rejection will still trigger one unhandled rejection.
198
- // Handling the rejection will not trigger unhandled rejections.
199
- entry = loadChunkAsyncUncached ( source , chunkPath ) . then ( resolve )
180
+ try {
181
+ // Load the chunk synchronously
182
+ loadChunkUncached ( chunkPath )
183
+ entry = loadedChunk
184
+ } catch ( e ) {
185
+ let errorMessage = `Failed to load chunk ${ chunkPath } `
186
+ if ( source ) {
187
+ errorMessage += ` from ${ stringifySourceInfo ( source ) } `
188
+ }
189
+
190
+ // Cache the failure promise, future requests will also get this same rejection
191
+ entry = Promise . reject (
192
+ new Error ( errorMessage , {
193
+ cause : e ,
194
+ } )
195
+ )
196
+ }
200
197
chunkCache . set ( chunkPath , entry )
201
198
}
202
199
// TODO: Return an instrumented Promise that React can use instead of relying on referential equality.
203
- return entry === null ? loadedChunk : entry
200
+ return entry
204
201
}
205
202
206
203
function loadChunkAsyncByUrl ( source : SourceInfo , chunkUrl : string ) {
0 commit comments