Skip to content

Commit 5b66bef

Browse files
authored
refactor(cache): align new cache snapshots with webpack (#15311)
1 parent 4a53f0c commit 5b66bef

12 files changed

Lines changed: 1265 additions & 126 deletions

File tree

crates/rspack_core/src/new_cache/file_cache_strategy.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use super::{
88
CacheKey, Etag,
99
cache_value::{CacheEntry, CacheValueDecoder, CacheValueEncoder, ErasedCacheValue},
1010
db::{Database, DatabaseFamily, DatabaseValue, DatabaseWrite},
11-
snapshot::{BuildDeps, Snapshot},
11+
snapshot::{BuildDeps, FileSystemInfo},
1212
validator::{CacheValidator, CacheValidatorResult},
1313
};
1414
use crate::cache::persistent::codec::CacheCodec;
@@ -53,7 +53,7 @@ impl FileCacheStrategy {
5353
rspack_pkg_version: String,
5454
cache_version: String,
5555
codec: Arc<CacheCodec>,
56-
snapshot: Snapshot,
56+
file_system_info: FileSystemInfo,
5757
build_deps: BuildDeps,
5858
) -> Result<Self> {
5959
let (base_path, database_path) = database_paths;
@@ -63,7 +63,7 @@ impl FileCacheStrategy {
6363
rspack_pkg_version,
6464
cache_version,
6565
codec.clone(),
66-
snapshot,
66+
file_system_info,
6767
build_deps,
6868
),
6969
codec,

crates/rspack_core/src/new_cache/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub use idle_file_cache::IdleFileCache;
2222
pub use memory_cache::{MemoryCache, MemoryCacheGetResult};
2323
use rspack_fs::ReadableFileSystem;
2424

25-
use self::snapshot::{BuildDeps, Snapshot};
25+
use self::snapshot::{BuildDeps, FileSystemInfo};
2626
use crate::{
2727
CompilationLogger, CompilationLogging, CompilerOptions, cache::persistent::codec::CacheCodec,
2828
};
@@ -53,7 +53,11 @@ pub fn create_cache(
5353
None
5454
};
5555
let codec = Arc::new(CacheCodec::new(project_root));
56-
let snapshot = Snapshot::new(options.snapshot.clone(), input_filesystem.clone());
56+
let file_system_info = FileSystemInfo::new(
57+
input_filesystem.clone(),
58+
options.snapshot.clone(),
59+
compiler_options.output.hash_function,
60+
);
5761
let build_deps = BuildDeps::new(
5862
&options.build_dependencies,
5963
input_filesystem,
@@ -73,7 +77,7 @@ pub fn create_cache(
7377
rspack_workspace::rspack_pkg_version!().to_string(),
7478
options.version.clone(),
7579
codec,
76-
snapshot,
80+
file_system_info,
7781
build_deps,
7882
) {
7983
Ok(strategy) => strategy,

crates/rspack_core/src/new_cache/snapshot/build_deps.rs

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::{collections::VecDeque, path::PathBuf, sync::Arc};
22

3+
use rspack_error::Result;
34
use rspack_fs::ReadableFileSystem;
45
use rspack_paths::{AssertUtf8, InternedPath, InternedPathSet};
56

6-
use super::{Snapshot, SnapshotEntry};
7+
use super::{FileSystemInfo, Snapshot, SnapshotValidationResult};
78
use crate::{
89
CompilationLogger,
910
cache::persistent::build_dependencies::{Helper, is_node_package_path},
@@ -22,6 +23,14 @@ pub enum BuildDepsValidationResult {
2223
},
2324
}
2425

26+
#[derive(Debug, Default)]
27+
pub struct ResolvedBuildDependencies {
28+
pub(crate) dependencies: InternedPathSet,
29+
pub(crate) files: InternedPathSet,
30+
pub(crate) contexts: InternedPathSet,
31+
pub(crate) missing: InternedPathSet,
32+
}
33+
2534
/// Build dependencies manager.
2635
#[derive(Debug)]
2736
pub struct BuildDeps {
@@ -51,21 +60,35 @@ impl BuildDeps {
5160
///
5261
/// For performance reasons, recursive searches stop at dependencies in
5362
/// `node_modules`.
63+
///
64+
/// See webpack's build dependency resolution implementation:
65+
/// https://github.com/webpack/webpack/blob/ce97d583e1cd8f3e47b70737de72e91b567a8497/lib/FileSystemInfo.js#L1873-L2523
5466
pub async fn resolve_dependencies(
5567
&mut self,
5668
current: &InternedPathSet,
5769
paths: impl Iterator<Item = InternedPath>,
58-
) -> InternedPathSet {
70+
) -> ResolvedBuildDependencies {
5971
let mut helper = Helper::new(self.fs.clone(), self.logger.clone());
60-
let mut added = InternedPathSet::default();
72+
let mut resolved = ResolvedBuildDependencies::default();
6173
let mut queue = VecDeque::new();
6274
queue.extend(self.pending.iter().cloned());
6375
queue.extend(paths);
6476

6577
while let Some(dependency) = queue.pop_front() {
66-
if current.contains(&dependency) || !added.insert(dependency.clone()) {
78+
if current.contains(&dependency) || !resolved.dependencies.insert(dependency.clone()) {
6779
continue;
6880
}
81+
match self.fs.metadata(dependency.assert_utf8()).await {
82+
Ok(metadata) if metadata.is_directory => {
83+
resolved.contexts.insert(dependency.clone());
84+
}
85+
Ok(_) => {
86+
resolved.files.insert(dependency.clone());
87+
}
88+
Err(_) => {
89+
resolved.missing.insert(dependency.clone());
90+
}
91+
}
6992
if is_node_package_path(&dependency) {
7093
continue;
7194
}
@@ -79,25 +102,44 @@ impl BuildDeps {
79102
}
80103

81104
self.pending.clear();
82-
added
105+
resolved
83106
}
84107

85108
/// Validate build dependencies.
86109
///
87110
/// If any build dependency changed, this method returns an invalid result.
88111
pub async fn validate_snapshot(
89112
&self,
113+
file_system_info: &FileSystemInfo,
90114
snapshot: &Snapshot,
91-
entries: &[SnapshotEntry],
115+
dependencies: &InternedPathSet,
92116
tracked_files: usize,
93-
) -> BuildDepsValidationResult {
94-
let (modified_files, removed_files) = snapshot.calc_modified_paths(entries).await;
95-
if !modified_files.is_empty() || !removed_files.is_empty() {
96-
return BuildDepsValidationResult::Invalid {
97-
modified_files,
117+
) -> Result<BuildDepsValidationResult> {
118+
let validation = file_system_info.check_snapshot_valid(snapshot).await?;
119+
let pending = self
120+
.pending
121+
.iter()
122+
.filter(|path| !dependencies.contains(*path))
123+
.cloned()
124+
.collect::<InternedPathSet>();
125+
match validation {
126+
SnapshotValidationResult::Valid if pending.is_empty() => {
127+
Ok(BuildDepsValidationResult::Valid { tracked_files })
128+
}
129+
SnapshotValidationResult::Valid => Ok(BuildDepsValidationResult::Invalid {
130+
modified_files: pending,
131+
removed_files: Default::default(),
132+
}),
133+
SnapshotValidationResult::Invalid {
134+
mut modified_files,
98135
removed_files,
99-
};
136+
} => {
137+
modified_files.extend(pending);
138+
Ok(BuildDepsValidationResult::Invalid {
139+
modified_files,
140+
removed_files,
141+
})
142+
}
100143
}
101-
BuildDepsValidationResult::Valid { tracked_files }
102144
}
103145
}

0 commit comments

Comments
 (0)