@@ -161,7 +161,9 @@ export function getChunkAssignments(
161
161
allEntries,
162
162
dependentEntriesByModule,
163
163
dynamicallyDependentEntriesByDynamicEntry,
164
- dynamicImportsByEntry
164
+ dynamicImportsByEntry,
165
+ dynamicallyDependentEntriesByAwaitedDynamicEntry,
166
+ awaitedDynamicImportsByEntry
165
167
} = analyzeModuleGraph ( entries ) ;
166
168
167
169
// Each chunk is identified by its position in this array
@@ -177,8 +179,18 @@ export function getChunkAssignments(
177
179
dynamicImportsByEntry ,
178
180
allEntries
179
181
) ;
182
+ const awaitedAlreadyLoadedAtomsByEntry = getAlreadyLoadedAtomsByEntry (
183
+ staticDependencyAtomsByEntry ,
184
+ dynamicallyDependentEntriesByAwaitedDynamicEntry ,
185
+ awaitedDynamicImportsByEntry ,
186
+ allEntries
187
+ ) ;
180
188
// This mutates the dependentEntries in chunkAtoms
181
- removeUnnecessaryDependentEntries ( chunkAtoms , alreadyLoadedAtomsByEntry ) ;
189
+ removeUnnecessaryDependentEntries (
190
+ chunkAtoms ,
191
+ alreadyLoadedAtomsByEntry ,
192
+ awaitedAlreadyLoadedAtomsByEntry
193
+ ) ;
182
194
const { chunks, sideEffectAtoms, sizeByAtom } =
183
195
getChunksWithSameDependentEntriesAndCorrelatedAtoms (
184
196
chunkAtoms ,
@@ -241,15 +253,21 @@ function analyzeModuleGraph(entries: Iterable<Module>): {
241
253
dependentEntriesByModule : Map < Module , Set < number > > ;
242
254
dynamicImportsByEntry : readonly ReadonlySet < number > [ ] ;
243
255
dynamicallyDependentEntriesByDynamicEntry : Map < number , Set < number > > ;
256
+ awaitedDynamicImportsByEntry : readonly ReadonlySet < number > [ ] ;
257
+ dynamicallyDependentEntriesByAwaitedDynamicEntry : Map < number , Set < number > > ;
244
258
} {
245
259
const dynamicEntryModules = new Set < Module > ( ) ;
260
+ const awaitedDynamicEntryModules = new Set < Module > ( ) ;
246
261
const dependentEntriesByModule = new Map < Module , Set < number > > ( ) ;
247
262
const allEntriesSet = new Set ( entries ) ;
248
263
const dynamicImportModulesByEntry : Set < Module > [ ] = new Array ( allEntriesSet . size ) ;
264
+ const awaitedDynamicImportModulesByEntry : Set < Module > [ ] = new Array ( allEntriesSet . size ) ;
249
265
let entryIndex = 0 ;
250
266
for ( const currentEntry of allEntriesSet ) {
251
267
const dynamicImportsForCurrentEntry = new Set < Module > ( ) ;
268
+ const awaitedDynamicImportsForCurrentEntry = new Set < Module > ( ) ;
252
269
dynamicImportModulesByEntry [ entryIndex ] = dynamicImportsForCurrentEntry ;
270
+ awaitedDynamicImportModulesByEntry [ entryIndex ] = awaitedDynamicImportsForCurrentEntry ;
253
271
const modulesToHandle = new Set ( [ currentEntry ] ) ;
254
272
for ( const module of modulesToHandle ) {
255
273
getOrCreate ( dependentEntriesByModule , module , getNewSet < number > ) . add ( entryIndex ) ;
@@ -267,6 +285,10 @@ function analyzeModuleGraph(entries: Iterable<Module>): {
267
285
dynamicEntryModules . add ( resolution ) ;
268
286
allEntriesSet . add ( resolution ) ;
269
287
dynamicImportsForCurrentEntry . add ( resolution ) ;
288
+ if ( resolution . includedDirectTopLevelAwaitingDynamicImporters . has ( currentEntry ) ) {
289
+ awaitedDynamicEntryModules . add ( resolution ) ;
290
+ awaitedDynamicImportsForCurrentEntry . add ( resolution ) ;
291
+ }
270
292
}
271
293
}
272
294
for ( const dependency of module . implicitlyLoadedBefore ) {
@@ -279,18 +301,33 @@ function analyzeModuleGraph(entries: Iterable<Module>): {
279
301
entryIndex ++ ;
280
302
}
281
303
const allEntries = [ ...allEntriesSet ] ;
282
- const { dynamicEntries, dynamicImportsByEntry } = getDynamicEntries (
304
+ const {
305
+ awaitedDynamicEntries,
306
+ awaitedDynamicImportsByEntry,
307
+ dynamicEntries,
308
+ dynamicImportsByEntry
309
+ } = getDynamicEntries (
283
310
allEntries ,
284
311
dynamicEntryModules ,
285
- dynamicImportModulesByEntry
312
+ dynamicImportModulesByEntry ,
313
+ awaitedDynamicEntryModules ,
314
+ awaitedDynamicImportModulesByEntry
286
315
) ;
287
316
return {
288
317
allEntries,
318
+ awaitedDynamicImportsByEntry,
289
319
dependentEntriesByModule,
320
+ dynamicallyDependentEntriesByAwaitedDynamicEntry : getDynamicallyDependentEntriesByDynamicEntry (
321
+ dependentEntriesByModule ,
322
+ awaitedDynamicEntries ,
323
+ allEntries ,
324
+ dynamicEntry => dynamicEntry . includedDirectTopLevelAwaitingDynamicImporters
325
+ ) ,
290
326
dynamicallyDependentEntriesByDynamicEntry : getDynamicallyDependentEntriesByDynamicEntry (
291
327
dependentEntriesByModule ,
292
328
dynamicEntries ,
293
- allEntries
329
+ allEntries ,
330
+ dynamicEntry => dynamicEntry . includedDynamicImporters
294
331
) ,
295
332
dynamicImportsByEntry
296
333
} ;
@@ -299,16 +336,42 @@ function analyzeModuleGraph(entries: Iterable<Module>): {
299
336
function getDynamicEntries (
300
337
allEntries : Module [ ] ,
301
338
dynamicEntryModules : Set < Module > ,
302
- dynamicImportModulesByEntry : Set < Module > [ ]
339
+ dynamicImportModulesByEntry : Set < Module > [ ] ,
340
+ awaitedDynamicEntryModules : Set < Module > ,
341
+ awaitedDynamicImportModulesByEntry : Set < Module > [ ]
303
342
) {
304
343
const entryIndexByModule = new Map < Module , number > ( ) ;
305
344
const dynamicEntries = new Set < number > ( ) ;
345
+ const awaitedDynamicEntries = new Set < number > ( ) ;
306
346
for ( const [ entryIndex , entry ] of allEntries . entries ( ) ) {
307
347
entryIndexByModule . set ( entry , entryIndex ) ;
308
348
if ( dynamicEntryModules . has ( entry ) ) {
309
349
dynamicEntries . add ( entryIndex ) ;
310
350
}
351
+ if ( awaitedDynamicEntryModules . has ( entry ) ) {
352
+ awaitedDynamicEntries . add ( entryIndex ) ;
353
+ }
311
354
}
355
+ const dynamicImportsByEntry = getDynamicImportsByEntry (
356
+ dynamicImportModulesByEntry ,
357
+ entryIndexByModule
358
+ ) ;
359
+ const awaitedDynamicImportsByEntry = getDynamicImportsByEntry (
360
+ awaitedDynamicImportModulesByEntry ,
361
+ entryIndexByModule
362
+ ) ;
363
+ return {
364
+ awaitedDynamicEntries,
365
+ awaitedDynamicImportsByEntry,
366
+ dynamicEntries,
367
+ dynamicImportsByEntry
368
+ } ;
369
+ }
370
+
371
+ function getDynamicImportsByEntry (
372
+ dynamicImportModulesByEntry : Set < Module > [ ] ,
373
+ entryIndexByModule : Map < Module , number >
374
+ ) : Set < number > [ ] {
312
375
const dynamicImportsByEntry : Set < number > [ ] = new Array ( dynamicImportModulesByEntry . length ) ;
313
376
let index = 0 ;
314
377
for ( const dynamicImportModules of dynamicImportModulesByEntry ) {
@@ -318,13 +381,14 @@ function getDynamicEntries(
318
381
}
319
382
dynamicImportsByEntry [ index ++ ] = dynamicImports ;
320
383
}
321
- return { dynamicEntries , dynamicImportsByEntry } ;
384
+ return dynamicImportsByEntry ;
322
385
}
323
386
324
387
function getDynamicallyDependentEntriesByDynamicEntry (
325
388
dependentEntriesByModule : ReadonlyMap < Module , ReadonlySet < number > > ,
326
389
dynamicEntries : ReadonlySet < number > ,
327
- allEntries : readonly Module [ ]
390
+ allEntries : readonly Module [ ] ,
391
+ getDynamicImporters : ( entry : Module ) => Iterable < Module >
328
392
) : Map < number , Set < number > > {
329
393
const dynamicallyDependentEntriesByDynamicEntry = new Map < number , Set < number > > ( ) ;
330
394
for ( const dynamicEntryIndex of dynamicEntries ) {
@@ -335,7 +399,7 @@ function getDynamicallyDependentEntriesByDynamicEntry(
335
399
) ;
336
400
const dynamicEntry = allEntries [ dynamicEntryIndex ] ;
337
401
for ( const importer of concatLazy ( [
338
- dynamicEntry . includedDynamicImporters ,
402
+ getDynamicImporters ( dynamicEntry ) ,
339
403
dynamicEntry . implicitlyLoadedAfter
340
404
] ) ) {
341
405
for ( const entry of dependentEntriesByModule . get ( importer ) ! ) {
@@ -444,14 +508,19 @@ function getAlreadyLoadedAtomsByEntry(
444
508
*/
445
509
function removeUnnecessaryDependentEntries (
446
510
chunkAtoms : ModulesWithDependentEntries [ ] ,
447
- alreadyLoadedAtomsByEntry : bigint [ ]
511
+ alreadyLoadedAtomsByEntry : bigint [ ] ,
512
+ awaitedAlreadyLoadedAtomsByEntry : bigint [ ]
448
513
) {
449
514
// Remove entries from dependent entries if a chunk is already loaded without
450
- // that entry.
515
+ // that entry. Do not remove already loaded atoms where all dynamic imports
516
+ // are awaited to avoid cycles in the output.
451
517
let chunkMask = 1n ;
452
518
for ( const { dependentEntries } of chunkAtoms ) {
453
519
for ( const entryIndex of dependentEntries ) {
454
- if ( ( alreadyLoadedAtomsByEntry [ entryIndex ] & chunkMask ) === chunkMask ) {
520
+ if (
521
+ ( alreadyLoadedAtomsByEntry [ entryIndex ] & chunkMask ) === chunkMask &&
522
+ ( awaitedAlreadyLoadedAtomsByEntry [ entryIndex ] & chunkMask ) === 0n
523
+ ) {
455
524
dependentEntries . delete ( entryIndex ) ;
456
525
}
457
526
}
0 commit comments