Skip to content

Commit

Permalink
feat: support magic comment chunk name basically
Browse files Browse the repository at this point in the history
  • Loading branch information
xusd320 committed Oct 10, 2024
1 parent 6e1188e commit 71a5f0d
Show file tree
Hide file tree
Showing 18 changed files with 283 additions and 73 deletions.
2 changes: 1 addition & 1 deletion crates/mako/src/ast/js_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl JsAst {
}

pub fn analyze_deps(&self, context: Arc<Context>) -> Vec<Dependency> {
let mut visitor = DepAnalyzer::new(self.unresolved_mark);
let mut visitor = DepAnalyzer::new(self.unresolved_mark, context.clone());
GLOBALS.set(&context.meta.script.globals, || {
self.ast.visit_with(&mut visitor);
visitor.dependencies
Expand Down
6 changes: 3 additions & 3 deletions crates/mako/src/config/code_splitting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use super::generic_usize::GenericUsizeDefault;
use crate::create_deserialize_fn;

#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq, Hash)]
pub enum AllowChunks {

Check warning on line 7 in crates/mako/src/config/code_splitting.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/config/code_splitting.rs#L6-L7

Added lines #L6 - L7 were not covered by tests
#[serde(rename = "all")]
All,
Expand Down Expand Up @@ -62,15 +62,15 @@ impl Default for CodeSplittingAdvancedOptions {
}
}

#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ChunkNameSuffixStrategy {

Check warning on line 66 in crates/mako/src/config/code_splitting.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/config/code_splitting.rs#L65-L66

Added lines #L65 - L66 were not covered by tests
#[serde(rename = "packageName")]
PackageName,
#[serde(rename = "dependentsHash")]
DependentsHash,
}

#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq, Hash)]

Check warning on line 73 in crates/mako/src/config/code_splitting.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/config/code_splitting.rs#L73

Added line #L73 was not covered by tests
#[serde(rename_all = "camelCase")]
pub struct ChunkGroup {
pub name: String,
Expand Down
148 changes: 105 additions & 43 deletions crates/mako/src/generate/group_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ use tracing::debug;

use crate::ast::file::parse_path;
use crate::compiler::Compiler;
use crate::config::ChunkGroup;
use crate::dev::update::UpdateResult;
use crate::generate::chunk::{Chunk, ChunkId, ChunkType};
use crate::generate::chunk_graph::ChunkGraph;
use crate::module::{ModuleId, ResolveType};
use crate::module::{generate_module_id, ModuleId, ResolveType};

pub type GroupUpdateResult = Option<(Vec<ChunkId>, Vec<(ModuleId, ChunkId, ChunkType)>)>;

Expand Down Expand Up @@ -44,22 +45,33 @@ impl Compiler {
ChunkType::Entry(entry.clone(), entry_chunk_name.to_string(), false),
&mut chunk_graph,
vec![],
&None,
);
let chunk_name = chunk.filename();
visited.insert(chunk.id.clone());
visited.insert((chunk.id.clone(), None));
edges.extend(
[dynamic_dependencies.clone(), worker_dependencies.clone()]
.concat()
.into_iter()
.map(|dep| (chunk.id.clone(), dep.generate(&self.context).into())),
.map(|dep| {
(
chunk.id.clone(),
match dep {
(_, Some(chunk_group)) => {
generate_module_id(chunk_group.name, &self.context).into()
}
(module_id, None) => module_id.generate(&self.context).into(),

Check warning on line 63 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L57-L63

Added lines #L57 - L63 were not covered by tests
},
)
}),

Check warning on line 66 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L66

Added line #L66 was not covered by tests
);
chunk_graph.add_chunk(chunk);

/* A worker can self-spawn from it's source file, that will leads to a circular dependencies,
* a real case is https://unpkg.com/browse/@antv/[email protected]/pkg-parallel/.
* Memorize handled workers to avoid infinite resolving
*/
let mut visited_workers = HashSet::<ModuleId>::new();
let mut visited_workers = HashSet::<(ModuleId, Option<ChunkGroup>)>::new();

// 抽离成两个函数处理动态依赖中可能有 worker 依赖、worker 依赖中可能有动态依赖的复杂情况
self.handle_dynamic_dependencies(
Expand Down Expand Up @@ -88,29 +100,47 @@ impl Compiler {
fn handle_dynamic_dependencies(
&self,
chunk_name: &str,
dynamic_dependencies: Vec<ModuleId>,
visited: &HashSet<ModuleId>,
dynamic_dependencies: Vec<(ModuleId, Option<ChunkGroup>)>,
visited: &HashSet<(ModuleId, Option<ChunkGroup>)>,
edges: &mut Vec<(ModuleId, ModuleId)>,
chunk_graph: &mut ChunkGraph,
visited_workers: &mut HashSet<ModuleId>,
visited_workers: &mut HashSet<(ModuleId, Option<ChunkGroup>)>,
) {
visit_modules(dynamic_dependencies, Some(visited.clone()), |head| {
let (chunk, dynamic_dependencies, mut worker_dependencies) = self.create_chunk(
head,
&head.0,
ChunkType::Async,
chunk_graph,
vec![chunk_name.to_string()],
&head.1,

Check warning on line 115 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L115

Added line #L115 was not covered by tests
);

worker_dependencies.retain(|w| !visited_workers.contains(w));

edges.extend(
[dynamic_dependencies.clone(), worker_dependencies.clone()]
.concat()
.into_iter()
.map(|dep| (chunk.id.clone(), dep.generate(&self.context).into())),
);
chunk_graph.add_chunk(chunk);
if let Some(exited_chunk) = chunk_graph.mut_chunk(&chunk.id) {
chunk

Check warning on line 121 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L120-L121

Added lines #L120 - L121 were not covered by tests
.modules
.iter()
.for_each(|m| exited_chunk.add_module(m.clone()));

Check warning on line 124 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L124

Added line #L124 was not covered by tests
} else {
edges.extend(
[dynamic_dependencies.clone(), worker_dependencies.clone()]

Check warning on line 127 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L126-L127

Added lines #L126 - L127 were not covered by tests
.concat()
.into_iter()
.map(|dep| {
(
chunk.id.clone(),
match dep {
(_, Some(chunk_group)) => {
generate_module_id(chunk_group.name, &self.context).into()
}
(module_id, None) => module_id.generate(&self.context).into(),

Check warning on line 137 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L130-L137

Added lines #L130 - L137 were not covered by tests
},
)
}),
);
chunk_graph.add_chunk(chunk);

Check warning on line 142 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L140-L142

Added lines #L140 - L142 were not covered by tests
}

self.handle_worker_dependencies(
chunk_name,
Expand All @@ -128,18 +158,19 @@ impl Compiler {
fn handle_worker_dependencies(
&self,
chunk_name: &str,
worker_dependencies: Vec<ModuleId>,
visited: &HashSet<ModuleId>,
worker_dependencies: Vec<(ModuleId, Option<ChunkGroup>)>,
visited: &HashSet<(ModuleId, Option<ChunkGroup>)>,
edges: &mut Vec<(ModuleId, ModuleId)>,
chunk_graph: &mut ChunkGraph,
visited_workers: &mut HashSet<ModuleId>,
visited_workers: &mut HashSet<(ModuleId, Option<ChunkGroup>)>,
) {
visit_modules(worker_dependencies, Some(visited.clone()), |head| {
let (chunk, dynamic_dependencies, mut worker_dependencies) = self.create_chunk(
head,
ChunkType::Worker(head.clone()),
&head.0,
ChunkType::Worker(head.0.clone()),

Check warning on line 170 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L170

Added line #L170 was not covered by tests
chunk_graph,
vec![chunk_name.to_string()],
&head.1,

Check warning on line 173 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L173

Added line #L173 was not covered by tests
);

worker_dependencies.retain(|w| !visited_workers.contains(w));
Expand All @@ -148,7 +179,17 @@ impl Compiler {
[dynamic_dependencies.clone(), worker_dependencies.clone()]
.concat()
.into_iter()
.map(|dep| (chunk.id.clone(), dep.generate(&self.context).into())),
.map(|dep| {
(
chunk.id.clone(),
match dep {
(_, Some(chunk_group)) => {
generate_module_id(chunk_group.name, &self.context).into()
}
(module_id, None) => module_id.generate(&self.context).into(),

Check warning on line 189 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L182-L189

Added lines #L182 - L189 were not covered by tests
},
)
}),

Check warning on line 192 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L192

Added line #L192 was not covered by tests
);

chunk_graph.add_chunk(chunk);
Expand Down Expand Up @@ -238,13 +279,17 @@ impl Compiler {
let async_chunk_modules = update_result
.added
.iter()
.filter(|module_id| {
.filter_map(|module_id| {

Check warning on line 282 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L282

Added line #L282 was not covered by tests
module_graph
.get_dependents(module_id)
.iter()
.any(|(_, dep)| dep.resolve_type == ResolveType::DynamicImport)
.find_map(|(_, dep)| match &dep.resolve_type {
ResolveType::DynamicImport(chunk_group) => {
Some((module_id.clone(), chunk_group.clone()))
}
_ => None,
})

Check warning on line 291 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L286-L291

Added lines #L286 - L291 were not covered by tests
})
.cloned()
.collect::<_>();

// create chunk for added async module
Expand Down Expand Up @@ -315,8 +360,10 @@ impl Compiler {
.get_dependencies(head)
.into_iter()
.filter(|(_, dep)| {
dep.resolve_type != ResolveType::DynamicImport
&& dep.resolve_type != ResolveType::Worker
!matches!(
dep.resolve_type,

Check warning on line 364 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L363-L364

Added lines #L363 - L364 were not covered by tests
ResolveType::DynamicImport(_) | ResolveType::Worker(_)
)
})
.collect::<Vec<_>>();
let mut next_module_ids = vec![];
Expand Down Expand Up @@ -376,32 +423,41 @@ impl Compiler {
})
}

#[allow(clippy::type_complexity)]
fn create_chunk(
&self,
entry_module_id: &ModuleId,
chunk_id: &ChunkId,
chunk_type: ChunkType,
chunk_graph: &mut ChunkGraph,
shared_chunk_names: Vec<String>,
) -> (Chunk, Vec<ModuleId>, Vec<ModuleId>) {
crate::mako_profile_function!(&entry_module_id.id);
chunk_group: &Option<ChunkGroup>,
) -> (
Chunk,
Vec<(ModuleId, Option<ChunkGroup>)>,
Vec<(ModuleId, Option<ChunkGroup>)>,
) {
crate::mako_profile_function!(&chunk_id.id);
let mut dynamic_entries = vec![];
let mut worker_entries = vec![];

let chunk_id = entry_module_id.generate(&self.context);
let mut chunk = Chunk::new(chunk_id.into(), chunk_type.clone());
let chunk_id_str = match chunk_group {
Some(chunk_group) => generate_module_id(chunk_group.name.clone(), &self.context),

Check warning on line 444 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L444

Added line #L444 was not covered by tests
None => chunk_id.generate(&self.context),
};
let mut chunk = Chunk::new(chunk_id_str.into(), chunk_type.clone());

let module_graph = self.context.module_graph.read().unwrap();

let mut chunk_deps = visit_modules(vec![entry_module_id.clone()], None, |head| {
let mut chunk_deps = visit_modules(vec![chunk_id.clone()], None, |head| {
let mut next_module_ids = vec![];

for (dep_module_id, dep) in module_graph.get_dependencies(head) {
match dep.resolve_type {
ResolveType::DynamicImport => {
dynamic_entries.push(dep_module_id.clone());
match &dep.resolve_type {
ResolveType::DynamicImport(chunk_group) => {
dynamic_entries.push((dep_module_id.clone(), chunk_group.clone()));

Check warning on line 457 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L456-L457

Added lines #L456 - L457 were not covered by tests
}
ResolveType::Worker => {
worker_entries.push(dep_module_id.clone());
ResolveType::Worker(chunk_group) => {
worker_entries.push((dep_module_id.clone(), chunk_group.clone()));

Check warning on line 460 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L459-L460

Added lines #L459 - L460 were not covered by tests
}
// skip shared modules from entry chunks, but except worker chunk modules
_ if matches!(chunk_type, ChunkType::Worker(_))
Expand Down Expand Up @@ -430,7 +486,7 @@ impl Compiler {

fn create_update_async_chunks(
&self,
async_module_ids: Vec<ModuleId>,
async_module_ids: Vec<(ModuleId, Option<ChunkGroup>)>,
chunk_graph: &mut ChunkGraph,
shared_chunk_names: Vec<String>,
) -> Vec<ChunkId> {
Expand All @@ -439,10 +495,11 @@ impl Compiler {

visit_modules(async_module_ids, None, |head| {
let (new_chunk, dynamic_dependencies, worker_dependencies) = self.create_chunk(
head,
&head.0,
ChunkType::Async,
chunk_graph,
shared_chunk_names.clone(),
&head.1,

Check warning on line 502 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L502

Added line #L502 was not covered by tests
);
let chunk_id = new_chunk.id.clone();

Expand All @@ -454,11 +511,16 @@ impl Compiler {
.map(|dep| {
(
chunk_id.clone(),
match chunk_graph.get_chunk_for_module(&dep) {
match chunk_graph.get_chunk_for_module(&dep.0) {

Check warning on line 514 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L514

Added line #L514 was not covered by tests
// ref existing chunk
Some(chunk) => chunk.id.clone(),
// ref new chunk
None => dep.generate(&self.context).into(),
None => match dep {
(_, Some(chunk_group)) => {
generate_module_id(chunk_group.name, &self.context).into()
}
(module_id, None) => module_id.generate(&self.context).into(),

Check warning on line 522 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L518-L522

Added lines #L518 - L522 were not covered by tests
},
},
)
}),
Expand All @@ -469,8 +531,8 @@ impl Compiler {
// continue to visit non-existing dynamic dependencies
dynamic_dependencies
.into_iter()
.filter(|dep| chunk_graph.get_chunk_for_module(dep).is_none())
.collect::<Vec<ModuleId>>()
.filter(|dep| chunk_graph.get_chunk_for_module(&dep.0).is_none())

Check warning on line 534 in crates/mako/src/generate/group_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/group_chunk.rs#L534

Added line #L534 was not covered by tests
.collect::<Vec<(ModuleId, Option<ChunkGroup>)>>()
});

// add edges
Expand Down
39 changes: 39 additions & 0 deletions crates/mako/src/generate/optimize_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::module::{Module, ModuleId, ModuleInfo};
use crate::resolve::{ResolvedResource, ResolverResource};
use crate::utils::{create_cached_regex, url_safe_base64_encode};

#[derive(Debug)]

Check warning on line 20 in crates/mako/src/generate/optimize_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/optimize_chunk.rs#L20

Added line #L20 was not covered by tests
pub struct OptimizeChunksInfo {
pub group_options: ChunkGroup,
pub module_to_chunks: IndexMap<ModuleId, Vec<ChunkId>>,
Expand All @@ -26,6 +27,7 @@ impl Compiler {
pub fn optimize_chunk(&self) {
crate::mako_profile_function!();
debug!("optimize chunk");

if let Some(optimize_options) = self.get_optimize_chunk_options() {
debug!("optimize options: {:?}", optimize_options);
// stage: prepare
Expand Down Expand Up @@ -59,6 +61,39 @@ impl Compiler {
}
}

// fn collect_magic_chunk_groups(&self) -> Vec<OptimizeChunksInfo> {
// let module_graph = self.context.module_graph.read().unwrap();
// let edge_filter = EdgeFiltered::from_fn(&module_graph.graph, |edge_ref| {
// edge_ref
// .weight()
// .iter()
// .any(|d| matches!(d.resolve_type, ResolveType::DynamicImport(Some(_))))
// });
// edge_filter
// .edge_references()
// .fold(Vec::new(), |mut acc, e| {
// acc.extend(
// e.weight()
// .iter()
// .filter_map(|d| {
// if let ResolveType::DynamicImport(Some(chunk_group)) = &d.resolve_type {
// Some(OptimizeChunksInfo {
// group_options: chunk_group.clone(),
// module_to_chunks: IndexMap::from_iter([(
// module_graph.graph[e.target()].id.clone(),
// vec![ChunkId::new(chunk_group.name.clone())],
// )]),
// })
// } else {
// None
// }
// })
// .collect::<Vec<_>>(),
// );
// acc
// })
// }

pub fn optimize_hot_update_chunk(&self, group_result: &GroupUpdateResult) {
crate::mako_profile_function!();
debug!("optimize hot update chunk");
Expand Down Expand Up @@ -451,7 +486,11 @@ impl Compiler {
// remove modules from original chunks and add edge to new chunk
for (module_id, chunk_ids) in &info.module_to_chunks {
for chunk_id in chunk_ids {
if chunk_id.id == info_chunk_id.id {

Check warning on line 489 in crates/mako/src/generate/optimize_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/optimize_chunk.rs#L489

Added line #L489 was not covered by tests
continue;
}
let chunk = chunk_graph.mut_chunk(chunk_id).unwrap();
println!("chunk {} remove module {}", chunk.id.id, module_id.id);

Check warning on line 493 in crates/mako/src/generate/optimize_chunk.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/optimize_chunk.rs#L493

Added line #L493 was not covered by tests

chunk.remove_module(module_id);

Expand Down
Loading

0 comments on commit 71a5f0d

Please sign in to comment.