Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion crates/rspack_core/src/compilation/build_module_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ mod graph_updater;
mod lazy_barrel_artifact;
mod module_executor;

use std::sync::atomic::Ordering;

use rspack_error::Result;
use rspack_util::tracing_preset::TRACING_BENCH_TARGET;
use tracing::instrument;

pub use self::{
artifact::{BuildModuleGraphArtifact, BuildModuleGraphArtifactState},
Expand All @@ -13,7 +17,36 @@ pub use self::{
},
module_executor::{ExecuteModuleId, ExecutedRuntimeModule, ModuleExecutor},
};
use crate::Compilation;
use crate::{Compilation, logger::Logger};

pub async fn build_module_graph_pass(compilation: &mut Compilation) -> Result<()> {
let logger = compilation.get_logger("rspack.Compiler");
let start = logger.time("build module graph");
compilation.do_build_module_graph().await?;
logger.time_end(start);
Ok(())
}

impl Compilation {
#[instrument("Compilation:build_module_graph",target=TRACING_BENCH_TARGET, skip_all)]
async fn do_build_module_graph(&mut self) -> Result<()> {
// run module_executor
if let Some(module_executor) = &mut self.module_executor {
let mut module_executor = std::mem::take(module_executor);
module_executor.hook_before_make(self).await?;
self.module_executor = Some(module_executor);
}

let artifact = self.build_module_graph_artifact.take();
self
.build_module_graph_artifact
.replace(build_module_graph(self, artifact).await?);

self.in_finish_make.store(true, Ordering::Release);

Ok(())
}
}

/// make module graph, support incremental rebuild
///
Expand Down
19 changes: 19 additions & 0 deletions crates/rspack_core/src/compilation/finish_make/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use rspack_error::Result;

use crate::{Compilation, SharedPluginDriver, logger::Logger};

pub async fn finish_make_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
) -> Result<()> {
let logger = compilation.get_logger("rspack.Compiler");
let start = logger.time("finish make hook");
plugin_driver
.compiler_hooks
.finish_make
.call(compilation)
.await?;
logger.time_end(start);

Ok(())
}
45 changes: 45 additions & 0 deletions crates/rspack_core/src/compilation/finish_module_graph/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::sync::atomic::Ordering;

use rspack_error::Result;
use rspack_util::tracing_preset::TRACING_BENCH_TARGET;
use tracing::instrument;

use crate::{
Compilation, cache::Cache, compilation::build_module_graph::finish_build_module_graph,
logger::Logger,
};

pub async fn finish_module_graph_pass(
compilation: &mut Compilation,
cache: &mut dyn Cache,
) -> Result<()> {
let logger = compilation.get_logger("rspack.Compiler");
let start = logger.time("finish compilation");
compilation.finish_build_module_graph().await?;
cache
.after_build_module_graph(&compilation.build_module_graph_artifact)
.await;
logger.time_end(start);

Ok(())
}

impl Compilation {
#[instrument("Compilation:finish",target=TRACING_BENCH_TARGET, skip_all)]
pub async fn finish_build_module_graph(&mut self) -> Result<()> {
self.in_finish_make.store(false, Ordering::Release);
// clean up the entry deps
let make_artifact = self.build_module_graph_artifact.take();
self
.build_module_graph_artifact
.replace(finish_build_module_graph(self, make_artifact).await?);
// sync assets to module graph from module_executor
if let Some(module_executor) = &mut self.module_executor {
let mut module_executor = std::mem::take(module_executor);
module_executor.hook_after_finish_modules(self).await?;
self.module_executor = Some(module_executor);
}
// make finished, make artifact should be readonly thereafter.
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
use rspack_error::Result;

use super::*;
use crate::logger::Logger;

impl Compilation {
#[instrument("Compilation:finish",target=TRACING_BENCH_TARGET, skip_all)]
pub async fn finish_build_module_graph(&mut self) -> Result<()> {
self.in_finish_make.store(false, Ordering::Release);
// clean up the entry deps
let make_artifact = self.build_module_graph_artifact.take();
self
.build_module_graph_artifact
.replace(finish_build_module_graph(self, make_artifact).await?);
// sync assets to module graph from module_executor
if let Some(module_executor) = &mut self.module_executor {
let mut module_executor = std::mem::take(module_executor);
module_executor.hook_after_finish_modules(self).await?;
self.module_executor = Some(module_executor);
}
// make finished, make artifact should be readonly thereafter.
Ok(())
}
pub async fn finish_modules_pass(compilation: &mut Compilation) -> Result<()> {
let dependencies_diagnostics_artifact = compilation.dependencies_diagnostics_artifact.clone();
let async_modules_artifact = compilation.async_modules_artifact.clone();
let diagnostics = compilation
.collect_build_module_graph_effects(
&mut dependencies_diagnostics_artifact.borrow_mut(),
&mut async_modules_artifact.borrow_mut(),
)
.await?;
compilation.extend_diagnostics(diagnostics);

Ok(())
}

impl Compilation {
#[tracing::instrument("Compilation:collect_build_module_graph_effects", skip_all)]
pub async fn collect_build_module_graph_effects(
&mut self,
Expand Down
21 changes: 21 additions & 0 deletions crates/rspack_core/src/compilation/make/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use rspack_error::Result;

use crate::{Compilation, SharedPluginDriver, cache::Cache, logger::Logger};

pub async fn make_hook_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
cache: &mut dyn Cache,
) -> Result<()> {
let logger = compilation.get_logger("rspack.Compiler");

cache
.before_build_module_graph(&mut compilation.build_module_graph_artifact)
.await;

let start = logger.time("make hook");
plugin_driver.compiler_hooks.make.call(compilation).await?;
logger.time_end(start);

Ok(())
}
28 changes: 6 additions & 22 deletions crates/rspack_core/src/compilation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ mod create_chunk_assets;
mod create_hash;
mod create_module_assets;
mod create_module_hashes;
mod finish_module;
mod finish_make;
mod finish_module_graph;
mod finish_modules;
mod make;
mod module_ids;
mod optimize_chunk_modules;
mod optimize_chunks;
Expand All @@ -19,6 +22,7 @@ mod optimize_tree;
mod process_assets;
mod run_passes;
mod runtime_requirements;
mod seal;
use std::{
collections::{VecDeque, hash_map},
fmt::{self, Debug},
Expand Down Expand Up @@ -74,8 +78,7 @@ use crate::{
SourceType, Stats, ValueCacheVersions,
build_chunk_graph::artifact::BuildChunkGraphArtifact,
compilation::build_module_graph::{
BuildModuleGraphArtifact, ModuleExecutor, UpdateParam, build_module_graph,
finish_build_module_graph, update_module_graph,
BuildModuleGraphArtifact, ModuleExecutor, UpdateParam, update_module_graph,
},
compiler::{CompilationRecords, CompilerId},
get_runtime_key,
Expand Down Expand Up @@ -990,25 +993,6 @@ impl Compilation {
ukey
}

#[instrument("Compilation:build_module_graph",target=TRACING_BENCH_TARGET, skip_all)]
pub async fn build_module_graph(&mut self) -> Result<()> {
// run module_executor
if let Some(module_executor) = &mut self.module_executor {
let mut module_executor = std::mem::take(module_executor);
module_executor.hook_before_make(self).await?;
self.module_executor = Some(module_executor);
}

let artifact = self.build_module_graph_artifact.take();
self
.build_module_graph_artifact
.replace(build_module_graph(self, artifact).await?);

self.in_finish_make.store(true, Ordering::Release);

Ok(())
}

pub async fn rebuild_module<T>(
&mut self,
module_identifiers: IdentifierSet,
Expand Down
11 changes: 9 additions & 2 deletions crates/rspack_core/src/compilation/optimize_chunk_modules/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
use super::*;
use crate::logger::Logger;

pub async fn optimize_chunk_modules_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
) -> Result<()> {
plugin_driver
let logger = compilation.get_logger("rspack.Compilation");
let start = logger.time("optimize chunk modules");

let result = plugin_driver
.compilation_hooks
.optimize_chunk_modules
.call(compilation)
.await
.map(|_| ())
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.optimizeChunkModules"))
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.optimizeChunkModules"));

logger.time_end(start);
result
}
6 changes: 6 additions & 0 deletions crates/rspack_core/src/compilation/optimize_chunks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use super::*;
use crate::logger::Logger;

pub async fn optimize_chunks_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
) -> Result<()> {
let logger = compilation.get_logger("rspack.Compilation");
let start = logger.time("optimize chunks");

while matches!(
plugin_driver
.compilation_hooks
Expand All @@ -13,5 +17,7 @@ pub async fn optimize_chunks_pass(
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.optimizeChunks"))?,
Some(true)
) {}

logger.time_end(start);
Ok(())
}
11 changes: 9 additions & 2 deletions crates/rspack_core/src/compilation/optimize_modules/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use super::*;
use crate::logger::Logger;

pub async fn optimize_modules_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
) -> Result<()> {
let logger = compilation.get_logger("rspack.Compilation");
let start = logger.time("optimize modules");

let mut diagnostics = vec![];
while matches!(
plugin_driver
Expand All @@ -16,10 +20,13 @@ pub async fn optimize_modules_pass(
) {}
compilation.extend_diagnostics(diagnostics);

plugin_driver
let result = plugin_driver
.compilation_hooks
.after_optimize_modules
.call(compilation)
.await
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.afterOptimizeModules"))
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.afterOptimizeModules"));

logger.time_end(start);
result
}
11 changes: 9 additions & 2 deletions crates/rspack_core/src/compilation/optimize_tree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
use super::*;
use crate::logger::Logger;

pub async fn optimize_tree_pass(
compilation: &mut Compilation,
plugin_driver: SharedPluginDriver,
) -> Result<()> {
plugin_driver
let logger = compilation.get_logger("rspack.Compilation");
let start = logger.time("optimize tree");

let result = plugin_driver
.compilation_hooks
.optimize_tree
.call(compilation)
.await
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.optimizeTree"))
.map_err(|e| e.wrap_err("caused by plugins in Compilation.hooks.optimizeTree"));

logger.time_end(start);
result
}
49 changes: 28 additions & 21 deletions crates/rspack_core/src/compilation/rspack_passes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ The compilation process is organized into independent modules, each responsible
compilation/
├── mod.rs # Main Compilation struct which exposes the public API
├── run_passes.rs # Pass driver invoked from Compiler that runs make + seal passes
├── build_module_graph/ # Module graph construction
│ └── finish_module/ # Finalize module graph, async modules, dependency diagnostics
├── make/ # make_hook_pass: make hook + cache.before_build_module_graph
├── build_module_graph/ # build_module_graph_pass: module graph construction
├── finish_make/ # finish_make_pass: finish_make hook
├── finish_module_graph/ # finish_module_graph_pass: finalize module graph + cache
├── finish_modules/ # finish_modules_pass: finish_modules hook, diagnostics, checkpoint
├── seal/ # seal_pass: seal hook
├── optimize_dependencies/ # optimizeDependencies hook + side effects artifact
├── build_chunk_graph/ # Chunk graph construction (code splitting cache + pass wrapper)
├── optimize_modules/ # optimizeModules + afterOptimizeModules hooks
├── optimize_chunks/ # optimizeChunks hook
├── optimize_tree/ # optimizeTree hook
├── optimize_chunk_modules # optimizeChunkModules hook
├── optimize_chunk_modules/ # optimizeChunkModules hook
├── module_ids/ # Module ID assignment + diagnostics
├── chunk_ids/ # Chunk ID assignment + diagnostics
├── assign_runtime_ids/ # Runtime ID assignment for runtime chunks
Expand All @@ -43,21 +47,24 @@ compilation/

`run_passes` orchestrates the full pipeline (make + seal) in this order:

1. Make: `make` hook → `build_module_graph` → `finish_make` hook → `finish_build_module_graph`
2. Collect make diagnostics (`collect_build_module_graph_effects`)
3. Incremental checkpoint (`module_graph`), freeze module static cache in production
4. Seal kickoff: `CompilationHooks::seal`
5. `optimize_dependencies_pass`
6. `build_chunk_graph_pass` → `optimize_modules_pass` → `optimize_chunks_pass`
7. `optimize_tree_pass` → `optimize_chunk_modules_pass`
8. `module_ids_pass` → `chunk_ids_pass` → `assign_runtime_ids`
9. `optimize_code_generation_pass`
10. `create_module_hashes_pass`
11. `code_generation_pass`
12. `runtime_requirements_pass`
13. `create_hash_pass` (also runs runtime module code generation)
14. `create_module_assets_pass`
15. `create_chunk_assets_pass`
16. `process_assets_pass`
17. `after_seal_pass`
18. Unfreeze module static cache in production
1. `make_hook_pass`: `make` hook + cache.before_build_module_graph
2. `build_module_graph_pass`: build module graph
3. `finish_make_pass`: `finish_make` hook
4. `finish_module_graph_pass`: `finish_build_module_graph` + cache.after_build_module_graph
5. `finish_modules_pass`: `finish_modules` hook, collect diagnostics, incremental checkpoint
6. Freeze module static cache in production
7. `seal_pass`: `seal` hook
8. `optimize_dependencies_pass`
9. `build_chunk_graph_pass` → `optimize_modules_pass` → `optimize_chunks_pass`
10. `optimize_tree_pass` → `optimize_chunk_modules_pass`
11. `module_ids_pass` → `chunk_ids_pass` → `assign_runtime_ids`
12. `optimize_code_generation_pass`
13. `create_module_hashes_pass`
14. `code_generation_pass`
15. `runtime_requirements_pass`
16. `create_hash_pass` (also runs runtime module code generation)
17. `create_module_assets_pass`
18. `create_chunk_assets_pass`
19. `process_assets_pass`
20. `after_seal_pass`
21. Unfreeze module static cache in production
Loading
Loading