Skip to content

Commit

Permalink
fix: ensure error for merged common async chunk (#712)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeachScript authored Nov 27, 2023
1 parent 34d0864 commit a93c482
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
9 changes: 8 additions & 1 deletion crates/mako/src/chunk_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ impl ChunkGraph {
}

pub fn get_chunks(&self) -> Vec<&Chunk> {
self.get_all_chunks()
.into_iter()
.filter(|c| !c.modules.is_empty())
.collect()
}

pub fn get_all_chunks(&self) -> Vec<&Chunk> {
self.graph.node_weights().collect()
}

Expand Down Expand Up @@ -90,7 +97,7 @@ impl ChunkGraph {
}

pub fn full_hash(&self, module_graph: &ModuleGraph) -> u64 {
let mut chunks = self.get_chunks();
let mut chunks = self.get_all_chunks();
chunks.sort_by_key(|c| c.id.id.clone());

let mut hasher: XxHash64 = Default::default();
Expand Down
2 changes: 1 addition & 1 deletion crates/mako/src/group_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl Compiler {
module_id: &ModuleId,
chunk_graph: &ChunkGraph,
) -> Vec<(ModuleId, String)> {
let chunks = chunk_graph.get_chunks();
let chunks = chunk_graph.get_all_chunks();

chunks
.iter()
Expand Down
32 changes: 7 additions & 25 deletions crates/mako/src/optimize_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl Compiler {
fn merge_minimal_async_chunks(&self, options: &OptimizeChunkOptions) {
let mut async_to_entry = vec![];
let chunk_graph = self.context.chunk_graph.read().unwrap();
let chunks = chunk_graph.get_chunks();
let chunks = chunk_graph.get_all_chunks();

// find minimal async chunks to merge to entry chunk
// TODO: continue to merge deep-level async chunk
Expand Down Expand Up @@ -193,7 +193,7 @@ impl Compiler {
modules_in_chunk: Option<Vec<(&ModuleId, &ChunkId, &ChunkType)>>,
) {
let chunk_graph = self.context.chunk_graph.read().unwrap();
let chunks = chunk_graph.get_chunks();
let chunks = chunk_graph.get_all_chunks();
let modules_in_chunk = match modules_in_chunk {
Some(modules_in_chunk) => modules_in_chunk,
None => chunks.iter().fold(vec![], |mut acc, chunk| {
Expand Down Expand Up @@ -383,17 +383,9 @@ impl Compiler {
}

fn apply_optimize_infos(&self, optimize_chunks_infos: &Vec<OptimizeChunksInfo>) {
let mut edges_map = HashMap::new();
let mut edges_map: HashMap<ModuleId, IndexSet<ModuleId>> = HashMap::new();
let mut chunk_graph = self.context.chunk_graph.write().unwrap();

fn insert_edges_map(map: &mut HashMap<ChunkId, IndexSet<ChunkId>>, k: ChunkId, v: ChunkId) {
if let Some(value) = map.get_mut(&k) {
value.insert(v);
} else {
map.insert(k, IndexSet::from([v]));
}
}

for info in optimize_chunks_infos {
// create new chunk
let info_chunk_id = ChunkId {
Expand All @@ -419,21 +411,11 @@ impl Compiler {

chunk.remove_module(module_id);

if chunk.modules.is_empty() {
// replace edge between empty chunk and its dependent chunks
for dependent_id in chunk_graph.dependents_chunk(chunk_id) {
chunk_graph.remove_edge(&dependent_id, chunk_id);
insert_edges_map(&mut edges_map, dependent_id, info_chunk_id.clone());
}

// remove all new edges from original chunk if it is empty
edges_map.remove(chunk_id);

// remove empty chunk from chunk graph
chunk_graph.remove_chunk(chunk_id);
// record edge between original chunk and new dependency chunks
if let Some(value) = edges_map.get_mut(chunk_id) {
value.insert(info_chunk_id.clone());
} else {
// record edge between original chunk and new dependency chunks
insert_edges_map(&mut edges_map, chunk_id.clone(), info_chunk_id.clone());
edges_map.insert(chunk_id.clone(), IndexSet::from([info_chunk_id.clone()]));
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions crates/mako/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ mod tests {
use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock};

use mako_core::indexmap::IndexSet;

use super::transform_js;
use crate::ast::{build_js_ast, js_ast_to_code};
use crate::chunk::{Chunk, ChunkType};
Expand Down Expand Up @@ -748,6 +750,22 @@ const require = window.require;
static_cache: Default::default(),
});

// add fake chunk for dynamic import
let mut chunk_graph = context.chunk_graph.write().unwrap();

chunk_graph.add_chunk(Chunk {
id: ModuleId {
id: "./foo".to_string(),
},
chunk_type: ChunkType::Async,
modules: IndexSet::from([ModuleId {
id: "./foo".to_string(),
}]),
content: None,
source_map: None,
});
drop(chunk_graph);

let mut ast = build_js_ast(path, origin, &context).unwrap();
transform_js(
&mut ast.ast,
Expand Down
29 changes: 20 additions & 9 deletions crates/mako/src/transformers/transform_dynamic_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,26 @@ impl VisitMut for DynamicImport<'_> {

let chunk_ids = match chunk {
Some(chunk) => {
let mut ids = chunk_graph
.sync_dependencies_chunk(&chunk.id)
.iter()
.map(|chunk_id| {
generate_module_id(chunk_id.id.clone(), self.context)
})
.collect::<Vec<_>>();
ids.push(chunk.id.generate(self.context));
ids
[
chunk_graph.sync_dependencies_chunk(&chunk.id),
vec![chunk.id.clone()],
]
.concat()
.iter()
.filter_map(|chunk_id| {
let id = generate_module_id(chunk_id.id.clone(), self.context);

// skip empty chunk because it will not be generated
if chunk_graph
.chunk(chunk_id)
.is_some_and(|c| !c.modules.is_empty())
{
Some(id)
} else {
None
}
})
.collect::<Vec<_>>()
}
// None means the original chunk has been optimized to entry chunk
None => vec![],
Expand Down

0 comments on commit a93c482

Please sign in to comment.