Skip to content

Commit dfcdf84

Browse files
kdy1alexkirsz
andauthored
feat(turbopack): Consider cycles while spliting modules (vercel/turborepo#4595)
### Description This is optimization for modules with cyclic dependencies between AST nodes. - Fixes WEB-706. ### Testing Instructions Look at `output.mdx` using GitHub diff view, and you can see it rendered by selecting `Open file` from the context menu. --------- Co-authored-by: Alex Kirszenberg <alex.kirszenberg@vercel.com>
1 parent c7fa87e commit dfcdf84

File tree

5 files changed

+792
-87
lines changed

5 files changed

+792
-87
lines changed

crates/turbopack-ecmascript/src/tree_shake/graph.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,6 @@ impl DepGraph {
370370
global_done: &mut FxHashSet<u32>,
371371
group_done: &mut FxHashSet<u32>,
372372
) -> bool {
373-
// TODO(WEB-706): Consider cycles
374-
//
375-
376373
let mut changed = false;
377374

378375
// Check deps of `start`.
@@ -416,6 +413,24 @@ impl DepGraph {
416413
}
417414
}
418415

416+
// Cycles should form a separate group
417+
for id in self.g.graph_ix.iter() {
418+
let ix = self.g.get_node(id);
419+
420+
if let Some(cycle) = cycles.iter().find(|v| v.contains(&ix)) {
421+
if cycle.iter().all(|v| !global_done.contains(v)) {
422+
let ids = cycle
423+
.iter()
424+
.map(|&ix| self.g.graph_ix[ix as usize].clone())
425+
.collect::<Vec<_>>();
426+
427+
global_done.extend(cycle.iter().copied());
428+
429+
groups.push((ids, Default::default()));
430+
}
431+
}
432+
}
433+
419434
// Expand **starting** nodes
420435
for (ix, id) in self.g.graph_ix.iter().enumerate() {
421436
// If a node is reachable from two or more nodes, it should be in a
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"exports":[
3+
["c1_3"],
4+
["c1_3", "c2_2"]
5+
]
6+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
3+
function d1() { }
4+
5+
6+
function d2() { }
7+
8+
function d3() { }
9+
10+
11+
12+
13+
export function c1_1() {
14+
return c1_2()
15+
}
16+
17+
function c1_2() {
18+
return c1_3(d1)
19+
}
20+
export function c1_3() {
21+
return c1_1(d2)
22+
}
23+
24+
25+
function c2_1() {
26+
return c2_2(d3)
27+
}
28+
29+
export function c2_2() {
30+
return c2_3()
31+
}
32+
function c2_3() {
33+
return c2_1()
34+
}
35+
36+
37+
c1_3()
38+
c2_2()

0 commit comments

Comments
 (0)