Skip to content

Commit ff7eb8f

Browse files
committed
feat(cache): port persistent module cache
1 parent a338733 commit ff7eb8f

26 files changed

Lines changed: 629 additions & 78 deletions

File tree

crates/node_binding/napi-binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,6 +2779,7 @@ export interface RawModuleRuleUse {
27792779

27802780
export interface RawNewCache {
27812781
codeGeneration: boolean
2782+
module: boolean
27822783
devtool: boolean
27832784
loader: boolean
27842785
minimize: boolean

crates/rspack/tests/snapshots/defaults__default_options.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,7 @@ CompilerOptions {
17511751
css: false,
17521752
new_cache: NewCacheOptions {
17531753
code_generation: false,
1754+
module: false,
17541755
devtool: false,
17551756
loader: false,
17561757
minimize: false,

crates/rspack_binding_api/src/raw_options/raw_experiments/raw_new_cache.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rspack_core::NewCacheOptions;
55
#[napi(object)]
66
pub struct RawNewCache {
77
pub code_generation: bool,
8+
pub module: bool,
89
pub devtool: bool,
910
pub loader: bool,
1011
pub minimize: bool,
@@ -14,6 +15,7 @@ impl From<RawNewCache> for NewCacheOptions {
1415
fn from(value: RawNewCache) -> Self {
1516
Self {
1617
code_generation: value.code_generation,
18+
module: value.module,
1719
devtool: value.devtool,
1820
loader: value.loader,
1921
minimize: value.minimize,

crates/rspack_core/src/cache/codec.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ use rspack_paths::Utf8PathBuf;
99

1010
/// Internal cacheable context for serialization
1111
#[derive(Debug, Clone)]
12-
struct Context {
12+
pub(crate) struct CacheCodecContext {
1313
portable_project_root: Option<Utf8PathBuf>,
14+
omit_module_factory_state: bool,
1415
}
1516

16-
impl rspack_cacheable::CacheableContext for Context {
17+
impl CacheCodecContext {
18+
pub(crate) fn omit_module_factory_state(&self) -> bool {
19+
self.omit_module_factory_state
20+
}
21+
}
22+
23+
impl rspack_cacheable::CacheableContext for CacheCodecContext {
1724
fn project_root(&self) -> Option<&Path> {
1825
self.portable_project_root.as_ref().map(|p| p.as_std_path())
1926
}
@@ -37,14 +44,24 @@ impl rspack_cacheable::CacheableContext for Context {
3744
/// ```
3845
#[derive(Debug, Clone)]
3946
pub struct CacheCodec {
40-
context: Context,
47+
context: CacheCodecContext,
4148
}
4249

4350
impl CacheCodec {
4451
pub fn new(portable_project_root: Option<Utf8PathBuf>) -> Self {
4552
Self {
46-
context: Context {
53+
context: CacheCodecContext {
54+
portable_project_root,
55+
omit_module_factory_state: false,
56+
},
57+
}
58+
}
59+
60+
pub(crate) fn new_for_module_cache(portable_project_root: Option<Utf8PathBuf>) -> Self {
61+
Self {
62+
context: CacheCodecContext {
4763
portable_project_root,
64+
omit_module_factory_state: true,
4865
},
4966
}
5067
}

crates/rspack_core/src/cache/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ pub use cache_entry::{
99
CachedExtractedComments, CachedMinimizeEntry, CachedSourceMapDevToolPluginEntry,
1010
};
1111
pub use codec::CacheCodec;
12+
pub(crate) use codec::CacheCodecContext;
1213
pub use options::{BuildDepsOptions, PersistentCacheOptions, StorageOptions};
1314
pub use snapshot::{PathMatcher, SnapshotOptions, SnapshotStrategyOptions};

crates/rspack_core/src/compilation/build_module_graph/graph_updater/repair/add.rs

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use rspack_error::Result;
22

3-
use super::{TaskContext, build::BuildTask, lazy::process_unlazy_dependencies};
3+
use super::{
4+
TaskContext,
5+
build::{BuildResultTask, BuildTask},
6+
lazy::process_unlazy_dependencies,
7+
};
48
use crate::{
5-
BoxModule, DependencyRef, ModuleIdentifier,
9+
BoxModule, BuildResult, DependencyRef, ModuleIdentifier,
610
compilation::build_module_graph::ForwardedIdSet,
711
module_graph::{ModuleGraph, ModuleGraphModule},
812
utils::task_loop::{Task, TaskResult, TaskType},
@@ -17,55 +21,69 @@ pub struct AddTask {
1721
pub from_unlazy: bool,
1822
}
1923

24+
enum ModuleBuild {
25+
Fresh(BoxModule),
26+
Cached(BuildResult),
27+
}
28+
2029
#[async_trait::async_trait]
2130
impl Task<TaskContext> for AddTask {
2231
fn get_task_type(&self) -> TaskType {
2332
TaskType::Main
2433
}
2534
async fn main_run(self: Box<Self>, context: &mut TaskContext) -> TaskResult<TaskContext> {
26-
let module_identifier = self.module.identifier();
27-
let module_graph = &mut context.artifact.module_graph;
35+
let Self {
36+
original_module_identifier,
37+
mut module,
38+
module_graph_module,
39+
dependencies,
40+
from_unlazy,
41+
} = *self;
42+
let module_identifier = module.identifier();
2843

2944
// reuse module for self referenced module
30-
if self.module.as_self_module().is_some() {
31-
let issuer = self
32-
.module_graph_module
45+
if module.as_self_module().is_some() {
46+
let issuer = module_graph_module
3347
.issuer()
3448
.identifier()
3549
.expect("self module should have issuer");
3650

3751
set_resolved_module(
38-
module_graph,
39-
self.original_module_identifier,
40-
self.dependencies,
52+
&mut context.artifact.module_graph,
53+
original_module_identifier,
54+
dependencies,
4155
*issuer,
4256
)?;
4357

4458
return Ok(vec![]);
4559
}
4660

47-
let forwarded_ids = ForwardedIdSet::from_dependencies(&self.dependencies);
61+
let forwarded_ids = ForwardedIdSet::from_dependencies(&dependencies);
4862

4963
// reuse module if module is already added by other dependency
50-
if module_graph
64+
if context
65+
.artifact
66+
.module_graph
5167
.module_graph_module_by_identifier(&module_identifier)
5268
.is_some()
5369
{
5470
set_resolved_module(
55-
module_graph,
56-
self.original_module_identifier,
57-
self.dependencies,
71+
&mut context.artifact.module_graph,
72+
original_module_identifier,
73+
dependencies,
5874
module_identifier,
5975
)?;
6076

61-
if self.from_unlazy {
77+
if from_unlazy {
6278
context
6379
.artifact
6480
.affected_modules
6581
.mark_as_add(&module_identifier);
6682
}
6783

68-
if module_graph
84+
if context
85+
.artifact
86+
.module_graph
6987
.module_by_identifier(&module_identifier)
7088
.is_some()
7189
{
@@ -77,7 +95,7 @@ impl Task<TaskContext> for AddTask {
7795
{
7896
if let Some(task) = process_unlazy_dependencies(
7997
&context.artifact.module_to_lazy_make,
80-
module_graph,
98+
&mut context.artifact.module_graph,
8199
forwarded_ids,
82100
module_identifier,
83101
) {
@@ -96,28 +114,54 @@ impl Task<TaskContext> for AddTask {
96114
return Ok(vec![]);
97115
}
98116

99-
module_graph.add_module_graph_module(*self.module_graph_module);
117+
let module_build = match context.module_cache.restore(module_identifier)? {
118+
Some(mut build_result) => {
119+
build_result.module.update_cache_module(&mut module);
120+
ModuleBuild::Cached(build_result)
121+
}
122+
None => ModuleBuild::Fresh(module),
123+
};
124+
125+
context
126+
.artifact
127+
.module_graph
128+
.add_module_graph_module(*module_graph_module);
100129

101130
context
102131
.exports_info_artifact
103132
.new_exports_info(module_identifier);
104133

105134
set_resolved_module(
106-
module_graph,
107-
self.original_module_identifier,
108-
self.dependencies,
135+
&mut context.artifact.module_graph,
136+
original_module_identifier,
137+
dependencies,
109138
module_identifier,
110139
)?;
111140

112-
tracing::trace!("Module added: {}", self.module.identifier());
141+
tracing::trace!("Module added: {module_identifier}");
113142
context
114143
.artifact
115144
.affected_modules
116145
.mark_as_add(&module_identifier);
146+
147+
let module = match module_build {
148+
ModuleBuild::Fresh(module) => module,
149+
ModuleBuild::Cached(mut build_result) => {
150+
if !context.module_needs_build(&mut build_result.module).await? {
151+
return Ok(vec![Box::new(BuildResultTask::cached(
152+
build_result,
153+
context.plugin_driver.clone(),
154+
forwarded_ids,
155+
))]);
156+
}
157+
build_result.module
158+
}
159+
};
160+
117161
Ok(vec![Box::new(BuildTask {
118162
compiler_id: context.compiler_id,
119163
compilation_id: context.compilation_id,
120-
module: self.module,
164+
module,
121165
resolver_factory: context.resolver_factory.clone(),
122166
compiler_options: context.compiler_options.clone(),
123167
loader_cache: context.cache.facade("loader"),
@@ -126,6 +170,7 @@ impl Task<TaskContext> for AddTask {
126170
runtime_template: context.runtime_template.create_module_code_template(),
127171
fs: context.fs.clone(),
128172
forwarded_ids,
173+
module_cache: context.module_cache.clone(),
129174
})])
130175
}
131176
}

0 commit comments

Comments
 (0)