@@ -17,7 +17,10 @@ use crate::{
17
17
18
18
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
19
19
pub enum ChunkReCreation {
20
- Entry ( String ) ,
20
+ Entry {
21
+ name : String ,
22
+ depend_on : Option < Vec < String > > ,
23
+ } ,
21
24
Normal ( NormalChunkRecreation ) ,
22
25
}
23
26
@@ -32,7 +35,10 @@ pub struct NormalChunkRecreation {
32
35
impl ChunkReCreation {
33
36
pub fn rebuild ( self , splitter : & mut CodeSplitter , compilation : & mut Compilation ) -> Result < ( ) > {
34
37
match self {
35
- ChunkReCreation :: Entry ( entry) => {
38
+ ChunkReCreation :: Entry {
39
+ name : entry,
40
+ depend_on : _,
41
+ } => {
36
42
let input = splitter. prepare_entry_input ( & entry, compilation) ?;
37
43
splitter. set_entry_runtime_and_depend_on ( & entry, compilation) ?;
38
44
splitter. prepare_entries ( std:: iter:: once ( input) . collect ( ) , compilation) ?;
@@ -249,7 +255,10 @@ impl CodeSplitter {
249
255
&& chunk_group. is_initial ( )
250
256
&& chunk_group. parents . is_empty ( )
251
257
{
252
- edges = vec ! [ ChunkReCreation :: Entry ( name) ] ;
258
+ edges = vec ! [ ChunkReCreation :: Entry {
259
+ name,
260
+ depend_on: None ,
261
+ } ] ;
253
262
}
254
263
255
264
// If the invalidated chunk group is an entrypoint, we must also invalidate any
@@ -567,14 +576,20 @@ impl CodeSplitter {
567
576
568
577
edges = compilation
569
578
. entries
570
- . keys ( )
571
- . map ( |name| ChunkReCreation :: Entry ( name. to_owned ( ) ) )
579
+ . iter ( )
580
+ . map ( |( name, entry_data) | ChunkReCreation :: Entry {
581
+ name : name. to_owned ( ) ,
582
+ depend_on : entry_data. options . depend_on . clone ( ) ,
583
+ } )
572
584
. collect ( ) ;
573
585
} else {
574
586
' outer: for ( entry, data) in & compilation. entries {
575
587
if !compilation. entrypoints . contains_key ( entry) {
576
588
// new entry
577
- edges. push ( ChunkReCreation :: Entry ( entry. to_owned ( ) ) ) ;
589
+ edges. push ( ChunkReCreation :: Entry {
590
+ name : entry. to_owned ( ) ,
591
+ depend_on : data. options . depend_on . clone ( ) ,
592
+ } ) ;
578
593
continue ' outer;
579
594
}
580
595
@@ -594,21 +609,60 @@ impl CodeSplitter {
594
609
for m in & curr_modules {
595
610
// there is new entry
596
611
if !prev_entry_modules. contains ( m) {
597
- edges. push ( ChunkReCreation :: Entry ( entry. to_owned ( ) ) ) ;
612
+ edges. push ( ChunkReCreation :: Entry {
613
+ name : entry. to_owned ( ) ,
614
+ depend_on : data. options . depend_on . clone ( ) ,
615
+ } ) ;
598
616
continue ' outer;
599
617
}
600
618
}
601
619
602
620
for m in prev_entry_modules {
603
621
if !curr_modules. contains ( & m) {
604
622
// there is removed entry modules
605
- edges. push ( ChunkReCreation :: Entry ( entry. to_owned ( ) ) ) ;
623
+ edges. push ( ChunkReCreation :: Entry {
624
+ name : entry. to_owned ( ) ,
625
+ depend_on : data. options . depend_on . clone ( ) ,
626
+ } ) ;
606
627
continue ' outer;
607
628
}
608
629
}
609
630
}
610
631
}
611
632
633
+ // For entries with dependencies (`dependOn`), we must ensure that the dependency
634
+ // is processed before the entry that depends on it. This is a topological sort.
635
+ edges. sort_unstable_by ( |a, b| {
636
+ let ( a_name, a_depend_on) = if let ChunkReCreation :: Entry { name, depend_on } = a {
637
+ ( name, depend_on)
638
+ } else {
639
+ return std:: cmp:: Ordering :: Equal ;
640
+ } ;
641
+
642
+ let ( b_name, b_depend_on) = if let ChunkReCreation :: Entry { name, depend_on } = b {
643
+ ( name, depend_on)
644
+ } else {
645
+ return std:: cmp:: Ordering :: Equal ;
646
+ } ;
647
+
648
+ let a_depends_on_b = a_depend_on
649
+ . as_deref ( )
650
+ . is_some_and ( |deps| deps. contains ( b_name) ) ;
651
+ let b_depends_on_a = b_depend_on
652
+ . as_deref ( )
653
+ . is_some_and ( |deps| deps. contains ( a_name) ) ;
654
+
655
+ // If a depends on b, b must come first (a > b).
656
+ // If b depends on a, a must come first (a < b).
657
+ // If there's no direct dependency, their relative order doesn't matter.
658
+ if a_depends_on_b {
659
+ std:: cmp:: Ordering :: Greater
660
+ } else if b_depends_on_a {
661
+ std:: cmp:: Ordering :: Less
662
+ } else {
663
+ std:: cmp:: Ordering :: Equal
664
+ }
665
+ } ) ;
612
666
for edge in edges {
613
667
edge. rebuild ( self , compilation) ?;
614
668
}
0 commit comments