Skip to content

Commit

Permalink
feat(turbopack): Consider cycles while spliting modules (#4595)
Browse files Browse the repository at this point in the history
### 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>
  • Loading branch information
kdy1 and alexkirsz committed Apr 25, 2023
1 parent 7f381a1 commit 0235c88
Show file tree
Hide file tree
Showing 5 changed files with 792 additions and 87 deletions.
21 changes: 18 additions & 3 deletions crates/turbopack-ecmascript/src/tree_shake/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,6 @@ impl DepGraph {
global_done: &mut FxHashSet<u32>,
group_done: &mut FxHashSet<u32>,
) -> bool {
// TODO(WEB-706): Consider cycles
//

let mut changed = false;

// Check deps of `start`.
Expand Down Expand Up @@ -416,6 +413,24 @@ impl DepGraph {
}
}

// Cycles should form a separate group
for id in self.g.graph_ix.iter() {
let ix = self.g.get_node(id);

if let Some(cycle) = cycles.iter().find(|v| v.contains(&ix)) {
if cycle.iter().all(|v| !global_done.contains(v)) {
let ids = cycle
.iter()
.map(|&ix| self.g.graph_ix[ix as usize].clone())
.collect::<Vec<_>>();

global_done.extend(cycle.iter().copied());

groups.push((ids, Default::default()));
}
}
}

// Expand **starting** nodes
for (ix, id) in self.g.graph_ix.iter().enumerate() {
// If a node is reachable from two or more nodes, it should be in a
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"exports":[
["c1_3"],
["c1_3", "c2_2"]
]
}
38 changes: 38 additions & 0 deletions crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@


function d1() { }


function d2() { }

function d3() { }




export function c1_1() {
return c1_2()
}

function c1_2() {
return c1_3(d1)
}
export function c1_3() {
return c1_1(d2)
}


function c2_1() {
return c2_2(d3)
}

export function c2_2() {
return c2_3()
}
function c2_3() {
return c2_1()
}


c1_3()
c2_2()

0 comments on commit 0235c88

Please sign in to comment.