Skip to content

Commit c693c7a

Browse files
committed
fix: afterResolve in ContextModuleFactory should be AsyncSeriesWaterfallHook
1 parent adda728 commit c693c7a

File tree

9 files changed

+230
-62
lines changed

9 files changed

+230
-62
lines changed

crates/node_binding/binding.d.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,10 @@ export interface JsCompatSource {
291291
map?: Buffer
292292
}
293293

294-
export interface JsContextModuleFactoryAfterResolveArgs {
294+
export interface JsContextModuleFactoryAfterResolveResult {
295295
resource: string
296+
context: string
297+
request: string
296298
regExp?: string
297299
}
298300

crates/node_binding/src/plugins/interceptor.rs

+25-15
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use napi::{
1212
use rspack_binding_values::{
1313
CompatSource, JsAfterResolveData, JsAfterResolveOutput, JsAssetEmittedArgs, JsBeforeResolveArgs,
1414
JsBeforeResolveOutput, JsChunk, JsChunkAssetArgs, JsCompilation,
15-
JsContextModuleFactoryAfterResolveArgs, JsContextModuleFactoryAfterResolveResult, JsCreateData,
16-
JsExecuteModuleArg, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs,
17-
JsResolveForSchemeOutput, JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule,
15+
JsContextModuleFactoryAfterResolveResult, JsCreateData, JsExecuteModuleArg, JsModule,
16+
JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, JsResolveForSchemeOutput,
17+
JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule,
1818
};
1919
use rspack_core::{
2020
rspack_sources::SourceExt, AfterResolveResult, AssetEmittedInfo, BoxModule, Chunk, ChunkUkey,
@@ -445,8 +445,8 @@ pub struct RegisterJsTaps {
445445
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsAfterResolveData) => Promise<boolean | undefined>); stage: number; }>"
446446
)]
447447
pub register_context_module_factory_after_resolve_taps: RegisterFunction<
448-
JsContextModuleFactoryAfterResolveArgs,
449-
Promise<JsContextModuleFactoryAfterResolveResult>,
448+
JsContextModuleFactoryAfterResolveResult,
449+
Promise<Option<JsContextModuleFactoryAfterResolveResult>>,
450450
>,
451451
}
452452

@@ -675,7 +675,7 @@ define_register!(
675675
);
676676
define_register!(
677677
RegisterContextModuleFactoryAfterResolveTaps,
678-
tap = ContextModuleFactoryAfterResolveTap<JsContextModuleFactoryAfterResolveArgs, Promise<JsContextModuleFactoryAfterResolveResult>> @ ContextModuleFactoryAfterResolveHook,
678+
tap = ContextModuleFactoryAfterResolveTap<JsContextModuleFactoryAfterResolveResult, Promise<Option<JsContextModuleFactoryAfterResolveResult>>> @ ContextModuleFactoryAfterResolveHook,
679679
cache = true,
680680
sync = false,
681681
kind = RegisterJsTapKind::ContextModuleFactoryAfterResolve,
@@ -1236,20 +1236,30 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap
12361236

12371237
#[async_trait]
12381238
impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap {
1239-
async fn run(&self, result: &mut AfterResolveResult) -> rspack_error::Result<Option<bool>> {
1240-
let (ret, res) = self
1239+
async fn run(
1240+
&self,
1241+
mut result: AfterResolveResult,
1242+
) -> rspack_error::Result<Option<AfterResolveResult>> {
1243+
let js_result = self
12411244
.function
1242-
.call_with_promise(JsContextModuleFactoryAfterResolveArgs {
1245+
.call_with_promise(JsContextModuleFactoryAfterResolveResult {
12431246
resource: result.resource.to_owned(),
1247+
context: result.context.to_owned(),
1248+
request: result.request.to_owned(),
12441249
reg_exp: result.reg_exp.clone().map(|r| r.to_string()),
12451250
})
12461251
.await?;
1247-
result.resource = res.resource;
1248-
result.reg_exp = match res.reg_exp {
1249-
Some(r) => Some(RspackRegex::new(&r)?),
1250-
None => None,
1251-
};
1252-
Ok(ret)
1252+
match js_result {
1253+
Some(js_result) => {
1254+
result.resource = js_result.resource;
1255+
result.reg_exp = match js_result.reg_exp {
1256+
Some(r) => Some(RspackRegex::new(&r)?),
1257+
None => None,
1258+
};
1259+
Ok(Some(result))
1260+
}
1261+
None => Ok(None),
1262+
}
12531263
}
12541264

12551265
fn stage(&self) -> i32 {
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use napi_derive::napi;
22

33
#[napi(object)]
4-
pub struct JsContextModuleFactoryAfterResolveArgs {
4+
pub struct JsContextModuleFactoryAfterResolveResult {
55
pub resource: String,
6+
pub context: String,
7+
pub request: String,
68
pub reg_exp: Option<String>,
79
}
8-
9-
pub type JsContextModuleFactoryAfterResolveResult =
10-
(Option<bool>, JsContextModuleFactoryAfterResolveArgs);

crates/rspack_core/src/context_module_factory.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@ use crate::{
1212
SharedPluginDriver,
1313
};
1414

15+
#[derive(Clone)]
1516
pub struct AfterResolveResult {
1617
pub resource: String,
17-
// context: Context,
18+
pub context: String,
1819
// dependencies
1920
// layer
2021
// resolve_options
2122
// file_dependencies: HashSet<String>,
2223
// missing_dependencies: HashSet<String>,
2324
// context_dependencies: HashSet<String>,
24-
// request: String,
25+
pub request: String,
2526
// mode
2627
// recursive: bool,
2728
pub reg_exp: Option<RspackRegex>,
@@ -37,7 +38,7 @@ pub struct AfterResolveResult {
3738
}
3839

3940
define_hook!(ContextModuleFactoryBeforeResolve: AsyncSeriesBail(data: &mut ModuleFactoryCreateData) -> bool);
40-
define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesBail(data: &mut AfterResolveResult) -> bool);
41+
define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesWaterfall(data: AfterResolveResult) -> Option<AfterResolveResult>);
4142

4243
#[derive(Debug, Default)]
4344
pub struct ContextModuleFactoryHooks {
@@ -205,8 +206,7 @@ impl ContextModuleFactory {
205206
Err(err) => (Err(err), false),
206207
};
207208

208-
let mut context_module_options = None;
209-
let module = match resource_data {
209+
let (module, context_module_options) = match resource_data {
210210
Ok(ResolveResult::Resource(resource)) => {
211211
let options = ContextModuleOptions {
212212
addon: loader_request.to_string(),
@@ -216,11 +216,11 @@ impl ContextModuleFactory {
216216
resolve_options: data.resolve_options.clone(),
217217
context_options: dependency.options().clone(),
218218
};
219-
context_module_options = Some(options.clone());
220-
Box::new(ContextModule::new(
221-
options,
219+
let module = Box::new(ContextModule::new(
220+
options.clone(),
222221
plugin_driver.resolver_factory.clone(),
223-
))
222+
));
223+
(module, Some(options))
224224
}
225225
Ok(ResolveResult::Ignored) => {
226226
let ident = format!("{}/{}", data.context, specifier);
@@ -254,28 +254,32 @@ impl ContextModuleFactory {
254254
&self,
255255
context_module_options: &mut ContextModuleOptions,
256256
) -> Result<Option<ModuleFactoryResult>> {
257-
let mut after_resolve_result = AfterResolveResult {
257+
let context_options = &context_module_options.context_options;
258+
let after_resolve_result = AfterResolveResult {
258259
resource: context_module_options.resource.to_owned(),
259-
reg_exp: context_module_options.context_options.reg_exp.clone(),
260+
context: context_options.context.to_owned(),
261+
request: context_options.request.to_owned(),
262+
reg_exp: context_options.reg_exp.clone(),
260263
};
261264

262-
if let Some(false) = self
265+
match self
263266
.plugin_driver
264267
.context_module_factory_hooks
265268
.after_resolve
266-
.call(&mut after_resolve_result)
269+
.call(after_resolve_result)
267270
.await?
268271
{
269-
return Ok(None);
270-
}
271-
272-
context_module_options.resource = after_resolve_result.resource;
273-
context_module_options.context_options.reg_exp = after_resolve_result.reg_exp;
272+
Some(after_resolve_result) => {
273+
context_module_options.resource = after_resolve_result.resource;
274+
context_module_options.context_options.reg_exp = after_resolve_result.reg_exp;
274275

275-
let module = ContextModule::new(
276-
context_module_options.clone(),
277-
self.loader_resolver_factory.clone(),
278-
);
279-
Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module))))
276+
let module = ContextModule::new(
277+
context_module_options.clone(),
278+
self.loader_resolver_factory.clone(),
279+
);
280+
Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module))))
281+
}
282+
None => Ok(None),
283+
}
280284
}
281285
}

crates/rspack_macros/src/hook.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ impl Parse for DefineHookInput {
2929
"SyncSeriesBail" => ExecKind::SyncSeriesBail {
3030
ret: ExecKind::parse_ret(input)?,
3131
},
32+
"AsyncSeriesWaterfall" => {
33+
let ret = match ExecKind::parse_ret(input)? {
34+
Some(t) => t,
35+
None => {
36+
return Err(Error::new(
37+
input.span(),
38+
"Waterfall hooks must explicitly define a return type",
39+
))
40+
}
41+
};
42+
ExecKind::AsyncSeriesWaterfall { ret }
43+
}
3244
"AsyncSeries" => ExecKind::AsyncSeries,
3345
"AsyncParallel" => ExecKind::AsyncParallel,
3446
"SyncSeries" => ExecKind::SyncSeries,
@@ -142,6 +154,7 @@ impl DefineHookInput {
142154
enum ExecKind {
143155
AsyncSeries,
144156
AsyncSeriesBail { ret: Option<TypePath> },
157+
AsyncSeriesWaterfall { ret: TypePath },
145158
AsyncParallel,
146159
SyncSeries,
147160
SyncSeriesBail { ret: Option<TypePath> },
@@ -160,7 +173,10 @@ impl ExecKind {
160173

161174
pub fn is_async(&self) -> bool {
162175
match self {
163-
Self::AsyncSeries | Self::AsyncSeriesBail { .. } | Self::AsyncParallel => true,
176+
Self::AsyncSeries
177+
| Self::AsyncSeriesBail { .. }
178+
| Self::AsyncSeriesWaterfall { .. }
179+
| Self::AsyncParallel => true,
164180
Self::SyncSeries | Self::SyncSeriesBail { .. } => false,
165181
}
166182
}
@@ -174,6 +190,9 @@ impl ExecKind {
174190
quote! { rspack_hook::__macro_helper::Result<std::option::Option<()>> }
175191
}
176192
}
193+
Self::AsyncSeriesWaterfall { ret } => {
194+
quote! { rspack_hook::__macro_helper::Result<#ret> }
195+
}
177196
_ => quote! { rspack_hook::__macro_helper::Result<()> },
178197
}
179198
}
@@ -219,6 +238,18 @@ impl ExecKind {
219238
Ok(None)
220239
}
221240
}
241+
Self::AsyncSeriesWaterfall { .. } => {
242+
quote! {
243+
#additional_taps
244+
let mut data = #args;
245+
for tap in all_taps {
246+
if let Some(res) = tap.run(data.clone()).await? {
247+
data = res;
248+
}
249+
}
250+
Ok(Some(data))
251+
}
252+
}
222253
Self::AsyncParallel => {
223254
quote! {
224255
#additional_taps

packages/rspack/src/Compiler.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { assertNotNill } from "./util/assertNotNil";
4747
import { FileSystemInfoEntry } from "./FileSystemInfo";
4848
import { RuntimeGlobals } from "./RuntimeGlobals";
4949
import { tryRunOrWebpackError } from "./lib/HookWebpackError";
50-
import { CodeGenerationResult, ContextModuleFactoryResolveData, Module, ResolveData } from "./Module";
50+
import { CodeGenerationResult, ContextModuleFactoryAfterResolveResult, Module, ResolveData } from "./Module";
5151
import { canInherentFromParent } from "./builtin-plugin/base";
5252
import ExecuteModulePlugin from "./ExecuteModulePlugin";
5353
import { Chunk } from "./Chunk";
@@ -510,7 +510,7 @@ class Compiler {
510510
createData: arg.createData
511511
};
512512
const ret = await queried.promise(data);
513-
return [ret, data.createData];
513+
return [!!ret, ret];
514514
}
515515
),
516516
registerNormalModuleFactoryCreateModuleTaps: this.#createHookRegisterTaps(
@@ -546,23 +546,23 @@ class Compiler {
546546
this.#createHookRegisterTaps(
547547
binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve,
548548
() => this.compilationParams!.contextModuleFactory.hooks.afterResolve,
549-
queried => async (args: binding.JsContextModuleFactoryAfterResolveArgs) => {
550-
const resolveData: ContextModuleFactoryResolveData = {
549+
queried => async (args: binding.JsContextModuleFactoryAfterResolveResult) => {
550+
const resolveData: ContextModuleFactoryAfterResolveResult = {
551551
resource: args.resource,
552-
regExp: args.regExp ? new RegExp(args.regExp) : undefined
553-
// request: arg.request,
554-
// context: arg.context,
555-
// fileDependencies: arg.fileDependencies,
556-
// missingDependencies: arg.missingDependencies,
557-
// contextDependencies: arg.contextDependencies,
558-
// createData: arg.createData
552+
regExp: args.regExp ? new RegExp(args.regExp) : undefined,
553+
request: args.request,
554+
context: args.context,
559555
};
560556
const raw = await queried.promise(resolveData);
561557
const result = raw ? {
562558
resource: raw.resource,
563-
regExp: raw.regExp?.toString()
564-
} satisfies binding.JsContextModuleFactoryAfterResolveArgs : undefined;
565-
return [!!raw, result];
559+
context: '',
560+
request: '',
561+
regExp: raw.regExp?.toString(),
562+
// TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin.
563+
dependencies: [],
564+
} : undefined;
565+
return result;
566566
}
567567
)
568568
};

packages/rspack/src/ContextModuleFactory.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as liteTapable from "./lite-tapable";
2-
import { ContextModuleFactoryResolveData, ResolveData } from "./Module";
2+
import { ContextModuleFactoryAfterResolveResult, ResolveData } from "./Module";
33

44
export class ContextModuleFactory {
55
hooks: {
66
// TODO: second param resolveData
77
// resolveForScheme: HookMap<
88
// AsyncSeriesBailHook<[ResourceDataWithData], true | void>
99
// >;
10-
beforeResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>;
11-
afterResolve: liteTapable.AsyncSeriesBailHook<[ContextModuleFactoryResolveData], false | void | ContextModuleFactoryResolveData>;
10+
beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ResolveData], false | void>;
11+
afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], false | void | ContextModuleFactoryAfterResolveResult>;
1212
};
1313
constructor() {
1414
this.hooks = {

packages/rspack/src/Module.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ export type ResolveData = {
2626
createData?: CreateData;
2727
};
2828

29-
export type ContextModuleFactoryResolveData = {
29+
export type ContextModuleFactoryAfterResolveResult = {
3030
resource: string;
31+
context: string
32+
request: string
3133
regExp?: RegExp;
3234
}
3335

0 commit comments

Comments
 (0)