Skip to content

Commit b5fc80f

Browse files
authored
fix: should update alias resolution when a higher-priority file is created in watch mode (#11643)
1 parent 873e2cd commit b5fc80f

File tree

10 files changed

+118
-111
lines changed

10 files changed

+118
-111
lines changed

crates/rspack_core/src/cache/persistent/occasion/make/mod.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::sync::Arc;
55

66
use rspack_collections::IdentifierSet;
77
use rspack_error::Result;
8-
use rustc_hash::FxHashSet as HashSet;
8+
use rustc_hash::FxHashSet;
99

1010
use super::super::{Storage, cacheable_context::CacheableContext};
1111
use crate::{
@@ -85,17 +85,18 @@ impl MakeOccasion {
8585
make_failed_module.insert(mid);
8686
}
8787
}
88+
8889
// recovery make_failed_dependencies
89-
let mut make_failed_dependencies = HashSet::default();
90+
let mut make_failed_dependencies = FxHashSet::default();
9091
for (dep_id, dep) in mg.dependencies() {
91-
if let Some(info) = FactorizeInfo::get_from(dep)
92-
&& !info.is_success()
93-
{
94-
make_failed_dependencies.insert(dep_id);
92+
if let Some(info) = FactorizeInfo::get_from(dep) {
93+
if !info.is_success() {
94+
make_failed_dependencies.insert(dep_id);
95+
}
9596
let resource = dep_id.into();
96-
file_dep.add_files(&resource, &info.file_dependencies());
97-
context_dep.add_files(&resource, &info.context_dependencies());
98-
missing_dep.add_files(&resource, &info.missing_dependencies());
97+
file_dep.add_files(&resource, info.file_dependencies());
98+
context_dep.add_files(&resource, info.context_dependencies());
99+
missing_dep.add_files(&resource, info.missing_dependencies());
99100
}
100101
}
101102

crates/rspack_core/src/compilation/make/artifact.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -113,25 +113,27 @@ impl MakeArtifact {
113113
.expect("should have mgm");
114114
for dep_id in mgm
115115
.all_dependencies
116-
.iter()
117-
.chain(mgm.incoming_connections())
116+
.clone()
117+
.into_iter()
118+
.chain(mgm.incoming_connections().clone())
118119
{
119-
if !self.make_failed_dependencies.remove(dep_id) {
120-
continue;
120+
self.make_failed_dependencies.remove(&dep_id);
121+
122+
let dep = mg
123+
.dependency_by_id_mut(&dep_id)
124+
.expect("should have dependency");
125+
if let Some(info) = FactorizeInfo::revoke(dep) {
126+
let resource_id = ResourceId::from(dep_id);
127+
self
128+
.file_dependencies
129+
.remove_files(&resource_id, info.file_dependencies());
130+
self
131+
.context_dependencies
132+
.remove_files(&resource_id, info.context_dependencies());
133+
self
134+
.missing_dependencies
135+
.remove_files(&resource_id, info.missing_dependencies());
121136
}
122-
// make failed dependencies clean it.
123-
let dep = mg.dependency_by_id(dep_id).expect("should have dependency");
124-
let info = FactorizeInfo::get_from(dep).expect("should have factorize info");
125-
let resource_id = ResourceId::from(dep_id);
126-
self
127-
.file_dependencies
128-
.remove_files(&resource_id, &info.file_dependencies());
129-
self
130-
.context_dependencies
131-
.remove_files(&resource_id, &info.context_dependencies());
132-
self
133-
.missing_dependencies
134-
.remove_files(&resource_id, &info.missing_dependencies());
135137
}
136138

137139
self.revoked_modules.insert(*module_identifier);
@@ -145,24 +147,25 @@ impl MakeArtifact {
145147
/// If `force` is true, the dependency will be completely removed, and nothing will be returned.
146148
/// This function will update index on MakeArtifact.
147149
pub fn revoke_dependency(&mut self, dep_id: &DependencyId, force: bool) -> Vec<BuildDependency> {
148-
let mut mg = ModuleGraph::new([None, None], Some(&mut self.module_graph_partial));
150+
self.make_failed_dependencies.remove(dep_id);
149151

150-
let revoke_dep_ids = if self.make_failed_dependencies.remove(dep_id) {
151-
// make failed dependencies clean it.
152-
let dep = mg.dependency_by_id(dep_id).expect("should have dependency");
153-
let info = FactorizeInfo::get_from(dep).expect("should have factorize info");
152+
let mut mg = ModuleGraph::new([None, None], Some(&mut self.module_graph_partial));
153+
let revoke_dep_ids = if let Some(factorize_info) = mg
154+
.dependency_by_id_mut(dep_id)
155+
.and_then(FactorizeInfo::revoke)
156+
{
154157
let resource_id = ResourceId::from(dep_id);
155158
self
156159
.file_dependencies
157-
.remove_files(&resource_id, &info.file_dependencies());
160+
.remove_files(&resource_id, factorize_info.file_dependencies());
158161
self
159162
.context_dependencies
160-
.remove_files(&resource_id, &info.context_dependencies());
163+
.remove_files(&resource_id, factorize_info.context_dependencies());
161164
self
162165
.missing_dependencies
163-
.remove_files(&resource_id, &info.missing_dependencies());
166+
.remove_files(&resource_id, factorize_info.missing_dependencies());
164167
// related_dep_ids will contain dep_id it self
165-
info.related_dep_ids().into_owned()
168+
factorize_info.related_dep_ids().to_vec()
166169
} else {
167170
vec![*dep_id]
168171
};

crates/rspack_core/src/compilation/make/graph_updater/repair/factorize.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,22 @@ impl Task<TaskContext> for FactorizeResultTask {
171171
} = *self;
172172

173173
let artifact = &mut context.artifact;
174-
if !factorize_info.diagnostics().is_empty() {
175-
let resource_id = ResourceId::from(*dependencies[0].id());
176-
artifact
177-
.file_dependencies
178-
.add_files(&resource_id, &factorize_info.file_dependencies());
179-
artifact
180-
.context_dependencies
181-
.add_files(&resource_id, &factorize_info.context_dependencies());
182-
artifact
183-
.missing_dependencies
184-
.add_files(&resource_id, &factorize_info.missing_dependencies());
174+
if !factorize_info.is_success() {
185175
artifact
186176
.make_failed_dependencies
187177
.insert(*dependencies[0].id());
188178
}
179+
let resource_id = ResourceId::from(*dependencies[0].id());
180+
artifact
181+
.file_dependencies
182+
.add_files(&resource_id, factorize_info.file_dependencies());
183+
artifact
184+
.context_dependencies
185+
.add_files(&resource_id, factorize_info.context_dependencies());
186+
artifact
187+
.missing_dependencies
188+
.add_files(&resource_id, factorize_info.missing_dependencies());
189+
189190
// write factorize_info to dependencies[0] and set success factorize_info to others
190191
for dep in &mut dependencies {
191192
let dep_factorize_info = if let Some(d) = dep.as_context_dependency_mut() {
Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::borrow::Cow;
2-
31
use rspack_cacheable::cacheable;
42
use rspack_error::Diagnostic;
53
use rspack_paths::ArcPathSet;
@@ -8,16 +6,12 @@ use super::{BoxDependency, DependencyId};
86

97
#[cacheable]
108
#[derive(Debug, Clone, Default)]
11-
pub enum FactorizeInfo {
12-
#[default]
13-
Success,
14-
Failed {
15-
related_dep_ids: Vec<DependencyId>,
16-
file_dependencies: ArcPathSet,
17-
context_dependencies: ArcPathSet,
18-
missing_dependencies: ArcPathSet,
19-
diagnostics: Vec<Diagnostic>,
20-
},
9+
pub struct FactorizeInfo {
10+
related_dep_ids: Vec<DependencyId>,
11+
file_dependencies: ArcPathSet,
12+
context_dependencies: ArcPathSet,
13+
missing_dependencies: ArcPathSet,
14+
diagnostics: Vec<Diagnostic>,
2115
}
2216

2317
impl FactorizeInfo {
@@ -28,16 +22,12 @@ impl FactorizeInfo {
2822
context_dependencies: ArcPathSet,
2923
missing_dependencies: ArcPathSet,
3024
) -> Self {
31-
if diagnostics.is_empty() {
32-
Self::Success
33-
} else {
34-
Self::Failed {
35-
related_dep_ids,
36-
file_dependencies,
37-
context_dependencies,
38-
missing_dependencies,
39-
diagnostics,
40-
}
25+
Self {
26+
related_dep_ids,
27+
file_dependencies,
28+
context_dependencies,
29+
missing_dependencies,
30+
diagnostics,
4131
}
4232
}
4333

@@ -51,52 +41,37 @@ impl FactorizeInfo {
5141
}
5242
}
5343

44+
pub fn revoke(dep: &mut BoxDependency) -> Option<FactorizeInfo> {
45+
if let Some(d) = dep.as_context_dependency_mut() {
46+
Some(std::mem::take(d.factorize_info_mut()))
47+
} else if let Some(d) = dep.as_module_dependency_mut() {
48+
Some(std::mem::take(d.factorize_info_mut()))
49+
} else {
50+
None
51+
}
52+
}
53+
5454
pub fn is_success(&self) -> bool {
55-
matches!(self, FactorizeInfo::Success)
55+
self.diagnostics.is_empty()
5656
}
5757

58-
pub fn related_dep_ids(&self) -> Cow<'_, [DependencyId]> {
59-
match &self {
60-
Self::Success => Cow::Owned(vec![]),
61-
Self::Failed {
62-
related_dep_ids, ..
63-
} => Cow::Borrowed(related_dep_ids),
64-
}
58+
pub fn related_dep_ids(&self) -> &[DependencyId] {
59+
&self.related_dep_ids
6560
}
6661

67-
pub fn file_dependencies(&self) -> Cow<'_, ArcPathSet> {
68-
match &self {
69-
Self::Success => Cow::Owned(Default::default()),
70-
Self::Failed {
71-
file_dependencies, ..
72-
} => Cow::Borrowed(file_dependencies),
73-
}
62+
pub fn file_dependencies(&self) -> &ArcPathSet {
63+
&self.file_dependencies
7464
}
7565

76-
pub fn context_dependencies(&self) -> Cow<'_, ArcPathSet> {
77-
match &self {
78-
Self::Success => Cow::Owned(Default::default()),
79-
Self::Failed {
80-
context_dependencies,
81-
..
82-
} => Cow::Borrowed(context_dependencies),
83-
}
66+
pub fn context_dependencies(&self) -> &ArcPathSet {
67+
&self.context_dependencies
8468
}
8569

86-
pub fn missing_dependencies(&self) -> Cow<'_, ArcPathSet> {
87-
match &self {
88-
Self::Success => Cow::Owned(Default::default()),
89-
Self::Failed {
90-
missing_dependencies,
91-
..
92-
} => Cow::Borrowed(missing_dependencies),
93-
}
70+
pub fn missing_dependencies(&self) -> &ArcPathSet {
71+
&self.missing_dependencies
9472
}
9573

96-
pub fn diagnostics(&self) -> Cow<'_, [Diagnostic]> {
97-
match &self {
98-
Self::Success => Cow::Owned(vec![]),
99-
Self::Failed { diagnostics, .. } => Cow::Borrowed(diagnostics),
100-
}
74+
pub fn diagnostics(&self) -> &[Diagnostic] {
75+
&self.diagnostics
10176
}
10277
}

crates/rspack_core/src/normal_module_factory.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,6 @@ impl NormalModuleFactory {
478478
resource_data.resource().to_owned()
479479
};
480480

481-
let file_dependency = resource_data.path().map(|p| p.to_owned());
482-
483481
let resolved_module_type =
484482
self.calculate_module_type(match_module_type, &resolved_module_rules);
485483
let resolved_module_layer =
@@ -586,9 +584,6 @@ impl NormalModuleFactory {
586584
.call(data, &mut create_data, &mut module)
587585
.await?;
588586

589-
if let Some(file_dependency) = file_dependency {
590-
data.add_file_dependency(file_dependency.into_std_path_buf());
591-
}
592587
data.add_file_dependencies(file_dependencies);
593588
data.add_missing_dependencies(missing_dependencies);
594589

tests/rspack-test/configCases/context/missing-dependency/rspack.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ module.exports = {
66
{
77
apply(compiler) {
88
compiler.hooks.done.tap("DonePlugin", stats => {
9-
expect(Array.from(stats.compilation.missingDependencies)).toEqual([
9+
expect(Array.from(stats.compilation.missingDependencies)).toContain(
1010
path.resolve(__dirname, "./lang")
11-
]);
11+
);
1212
});
1313
}
1414
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "a";
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import result from 'multi-alias';
2+
3+
it('should update alias resolution when a higher-priority file is created in watch mode', () => {
4+
switch (WATCH_STEP) {
5+
case "0":
6+
// Initial build:
7+
// `b.js` does not exist, so it should fall back to `a.js`.
8+
expect(result).toBe("a")
9+
break;
10+
case "1":
11+
// After update (b.js is created):
12+
// `b.js` now exists and has higher priority in the alias array.
13+
// The build should now resolve to `b.js`.
14+
expect(result).toBe("b")
15+
break;
16+
default:
17+
throw new Error('unexpected update');
18+
}
19+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default "b";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/** @type {import("@rspack/core").Configuration} */
2+
module.exports = {
3+
resolve: {
4+
alias: {
5+
"multi-alias": [
6+
"./b",
7+
"./a"
8+
]
9+
}
10+
}
11+
};

0 commit comments

Comments
 (0)