Skip to content

Commit 91e1e86

Browse files
committed
refactor: add collect_module_graph_effects
1 parent cb2a294 commit 91e1e86

File tree

26 files changed

+395
-250
lines changed

26 files changed

+395
-250
lines changed

crates/rspack_binding_api/src/module_graph.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ impl JsModuleGraph {
257257
#[napi(ts_args_type = "module: Module")]
258258
pub fn is_async(&self, module: ModuleObjectRef) -> napi::Result<bool> {
259259
let (compilation, _) = self.as_ref()?;
260-
Ok(ModuleGraph::is_async(compilation, &module.identifier))
260+
Ok(ModuleGraph::is_async(
261+
&compilation.collect_build_module_graph_effects_artifact,
262+
&module.identifier,
263+
))
261264
}
262265
}

crates/rspack_binding_api/src/plugins/interceptor.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ use rspack_core::{
4141
NormalModuleFactoryFactorizeHook, NormalModuleFactoryResolve,
4242
NormalModuleFactoryResolveForScheme, NormalModuleFactoryResolveForSchemeHook,
4343
NormalModuleFactoryResolveHook, NormalModuleFactoryResolveResult, ResourceData, RuntimeGlobals,
44-
Scheme, parse_resource, rspack_sources::RawStringSource,
44+
Scheme, collect_module_graph_effects::artifact::CollectModuleGraphEffectsArtifact,
45+
incremental::Mutations, parse_resource, rspack_sources::RawStringSource,
4546
};
4647
use rspack_hash::RspackHash;
4748
use rspack_hook::{Hook, Interceptor};
@@ -1211,7 +1212,11 @@ impl CompilationExecuteModule for CompilationExecuteModuleTap {
12111212

12121213
#[async_trait]
12131214
impl CompilationFinishModules for CompilationFinishModulesTap {
1214-
async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> {
1215+
async fn run(
1216+
&self,
1217+
compilation: &mut Compilation,
1218+
_artifacts: &mut CollectModuleGraphEffectsArtifact,
1219+
) -> rspack_error::Result<()> {
12151220
let compilation = JsCompilationWrapper::new(compilation);
12161221
self.function.call_with_promise(compilation).await
12171222
}

crates/rspack_core/src/artifacts/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rspack_collections::{IdentifierMap, IdentifierSet, UkeyMap};
2-
use rspack_error::Diagnostic;
32

43
use crate::{ChunkRenderResult, ChunkUkey, ModuleId, RuntimeGlobals, chunk_graph_chunk::ChunkId};
54

@@ -23,7 +22,7 @@ pub use side_effects_do_optimize_artifact::*;
2322

2423
pub type AsyncModulesArtifact = IdentifierSet;
2524
pub type ImportedByDeferModulesArtifact = IdentifierSet;
26-
pub type DependenciesDiagnosticsArtifact = IdentifierMap<Vec<Diagnostic>>;
25+
2726
pub type ModuleIdsArtifact = IdentifierMap<ModuleId>;
2827
pub type ChunkIdsArtifact = UkeyMap<ChunkUkey, ChunkId>;
2928
pub type CgcRuntimeRequirementsArtifact = UkeyMap<ChunkUkey, RuntimeGlobals>;

crates/rspack_core/src/chunk_graph/chunk_graph_module.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,11 @@ impl ChunkGraph {
383383
.hash(&mut hasher);
384384
module.source_types(&mg).dyn_hash(&mut hasher);
385385

386-
ModuleGraph::is_async(compilation, &module_identifier).dyn_hash(&mut hasher);
386+
ModuleGraph::is_async(
387+
&compilation.collect_build_module_graph_effects_artifact,
388+
&module_identifier,
389+
)
390+
.dyn_hash(&mut hasher);
387391
let exports_info =
388392
mg.get_prefetched_exports_info(&module_identifier, PrefetchExportsInfoMode::Full);
389393
let (entry, exports) = exports_info.meta();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use rspack_collections::{IdentifierMap, IdentifierSet};
2+
use rspack_error::Diagnostic;
3+
4+
use crate::incremental::Incremental;
5+
6+
#[derive(Debug, Default)]
7+
pub struct CollectModuleGraphEffectsArtifact {
8+
pub dependencies_diagnostics: DependenciesDiagnostics,
9+
pub async_module_info: IdentifierSet,
10+
pub incremental: Incremental,
11+
}
12+
13+
pub type DependenciesDiagnostics = IdentifierMap<Vec<Diagnostic>>;
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
pub mod artifact;
2+
use std::mem;
3+
4+
use rayon::iter::{IntoParallelRefIterator as _, ParallelIterator};
5+
use rspack_error::Result;
6+
7+
use crate::{
8+
Compilation, Logger as _,
9+
collect_module_graph_effects::artifact::{
10+
CollectModuleGraphEffectsArtifact, DependenciesDiagnostics,
11+
},
12+
incremental::{self, IncrementalPasses, Mutation},
13+
};
14+
pub async fn collect_build_module_graph_effects(compilation: &mut Compilation) -> Result<()> {
15+
let mut artifact = mem::take(&mut compilation.collect_build_module_graph_effects_artifact);
16+
collect_build_module_graph_effects_inner(compilation, &mut artifact).await?;
17+
compilation.diagnostics.extend(
18+
artifact
19+
.dependencies_diagnostics
20+
.clone()
21+
.into_values()
22+
.flatten(),
23+
);
24+
if let Some(mutations) = artifact.incremental.mutations_take() {
25+
for mutation in mutations {
26+
if let Some(mutations) = compilation.incremental.mutations_write() {
27+
mutations.add(mutation);
28+
}
29+
}
30+
}
31+
32+
compilation.collect_build_module_graph_effects_artifact = artifact;
33+
Ok(())
34+
}
35+
// collect build module graph effects for incremental compilation
36+
#[tracing::instrument("Compilation:collect_build_module_graph_effects", skip_all)]
37+
pub async fn collect_build_module_graph_effects_inner(
38+
ctx: &mut Compilation,
39+
artifact: &mut CollectModuleGraphEffectsArtifact,
40+
) -> Result<()> {
41+
let logger = ctx.get_logger("rspack.Compilation");
42+
if let Some(mutations) = artifact.incremental.mutations_write() {
43+
mutations.extend(
44+
ctx
45+
.build_module_graph_artifact
46+
.affected_dependencies
47+
.updated()
48+
.iter()
49+
.map(|&dependency| Mutation::DependencyUpdate { dependency }),
50+
);
51+
52+
mutations.extend(
53+
ctx
54+
.build_module_graph_artifact
55+
.affected_modules
56+
.removed()
57+
.iter()
58+
.map(|&module| Mutation::ModuleRemove { module }),
59+
);
60+
mutations.extend(
61+
ctx
62+
.build_module_graph_artifact
63+
.affected_modules
64+
.updated()
65+
.iter()
66+
.map(|&module| Mutation::ModuleUpdate { module }),
67+
);
68+
mutations.extend(
69+
ctx
70+
.build_module_graph_artifact
71+
.affected_modules
72+
.added()
73+
.iter()
74+
.map(|&module| Mutation::ModuleAdd { module }),
75+
);
76+
tracing::debug!(target: incremental::TRACING_TARGET, passes = %IncrementalPasses::MAKE, %mutations);
77+
}
78+
79+
let start = logger.time("finish modules");
80+
// finish_modules means the module graph (modules, connections, dependencies) are
81+
// frozen and start to optimize (provided exports, infer async, etc.) based on the
82+
// module graph, so any kind of change that affect these should be done before the
83+
// finish_modules
84+
85+
ctx
86+
.plugin_driver
87+
.clone()
88+
.compilation_hooks
89+
.finish_modules
90+
.call(ctx, artifact)
91+
.await?;
92+
93+
logger.time_end(start);
94+
95+
// https://github.com/webpack/webpack/blob/19ca74127f7668aaf60d59f4af8fcaee7924541a/lib/Compilation.js#L2988
96+
ctx.module_graph_cache_artifact.freeze();
97+
// Collect dependencies diagnostics at here to make sure:
98+
// 1. after finish_modules: has provide exports info
99+
// 2. before optimize dependencies: side effects free module hasn't been skipped
100+
collect_dependencies_diagnostics(ctx, artifact);
101+
ctx.module_graph_cache_artifact.unfreeze();
102+
Ok(())
103+
}
104+
#[tracing::instrument("Compilation:collect_dependencies_diagnostics", skip_all)]
105+
fn collect_dependencies_diagnostics(
106+
ctx: &Compilation,
107+
artifact: &mut CollectModuleGraphEffectsArtifact,
108+
) {
109+
let mutations = ctx
110+
.incremental
111+
.mutations_read(IncrementalPasses::DEPENDENCIES_DIAGNOSTICS);
112+
// TODO move diagnostic collect to make
113+
let modules = if let Some(mutations) = mutations
114+
&& !artifact.dependencies_diagnostics.is_empty()
115+
{
116+
let revoked_modules = mutations.iter().filter_map(|mutation| match mutation {
117+
Mutation::ModuleRemove { module } => Some(*module),
118+
_ => None,
119+
});
120+
for revoked_module in revoked_modules {
121+
artifact.dependencies_diagnostics.remove(&revoked_module);
122+
}
123+
let modules = mutations.get_affected_modules_with_module_graph(&ctx.get_module_graph());
124+
let logger = ctx.get_logger("rspack.incremental.dependenciesDiagnostics");
125+
logger.log(format!(
126+
"{} modules are affected, {} in total",
127+
modules.len(),
128+
ctx.get_module_graph().modules().len()
129+
));
130+
modules
131+
} else {
132+
ctx.get_module_graph().modules().keys().copied().collect()
133+
};
134+
let module_graph = ctx.get_module_graph();
135+
let module_graph_cache = &ctx.module_graph_cache_artifact;
136+
let dependencies_diagnostics: DependenciesDiagnostics = modules
137+
.par_iter()
138+
.map(|module_identifier| {
139+
let mgm = module_graph
140+
.module_graph_module_by_identifier(module_identifier)
141+
.expect("should have mgm");
142+
let diagnostics = mgm
143+
.all_dependencies
144+
.iter()
145+
.filter_map(|dependency_id| module_graph.dependency_by_id(dependency_id))
146+
.filter_map(|dependency| {
147+
dependency
148+
.get_diagnostics(&module_graph, module_graph_cache)
149+
.map(|diagnostics| {
150+
diagnostics.into_iter().map(|mut diagnostic| {
151+
diagnostic.module_identifier = Some(*module_identifier);
152+
diagnostic.loc = dependency.loc();
153+
diagnostic
154+
})
155+
})
156+
})
157+
.flatten()
158+
.collect::<Vec<_>>();
159+
(*module_identifier, diagnostics)
160+
})
161+
.collect();
162+
163+
artifact
164+
.dependencies_diagnostics
165+
.extend(dependencies_diagnostics);
166+
}

0 commit comments

Comments
 (0)