Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
SyMind committed May 6, 2024
1 parent adda728 commit 7ea5bec
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 20 deletions.
2 changes: 2 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ export interface JsCompatSource {

export interface JsContextModuleFactoryAfterResolveArgs {
resource: string
context: string
request: string
regExp?: string
}

Expand Down
8 changes: 5 additions & 3 deletions crates/node_binding/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,15 +1237,17 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap
#[async_trait]
impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap {
async fn run(&self, result: &mut AfterResolveResult) -> rspack_error::Result<Option<bool>> {
let (ret, res) = self
let (ret, js_result) = self
.function
.call_with_promise(JsContextModuleFactoryAfterResolveArgs {
resource: result.resource.to_owned(),
context: result.context.to_owned(),
request: result.request.to_owned(),
reg_exp: result.reg_exp.clone().map(|r| r.to_string()),
})
.await?;
result.resource = res.resource;
result.reg_exp = match res.reg_exp {
result.resource = js_result.resource;
result.reg_exp = match js_result.reg_exp {
Some(r) => Some(RspackRegex::new(&r)?),
None => None,
};
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_binding_values/src/context_module_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use napi_derive::napi;
#[napi(object)]
pub struct JsContextModuleFactoryAfterResolveArgs {
pub resource: String,
pub context: String,
pub request: String,
pub reg_exp: Option<String>,
}

Expand Down
12 changes: 8 additions & 4 deletions crates/rspack_core/src/context_module_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ use crate::{
SharedPluginDriver,
};

#[derive(Clone)]
pub struct AfterResolveResult {
pub resource: String,
// context: Context,
pub context: String,
// dependencies
// layer
// resolve_options
// file_dependencies: HashSet<String>,
// missing_dependencies: HashSet<String>,
// context_dependencies: HashSet<String>,
// request: String,
pub request: String,
// mode
// recursive: bool,
pub reg_exp: Option<RspackRegex>,
Expand All @@ -37,7 +38,7 @@ pub struct AfterResolveResult {
}

define_hook!(ContextModuleFactoryBeforeResolve: AsyncSeriesBail(data: &mut ModuleFactoryCreateData) -> bool);
define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesBail(data: &mut AfterResolveResult) -> bool);
define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesWaterfall(data: AfterResolveResult) -> AfterResolveResult);

#[derive(Debug, Default)]
pub struct ContextModuleFactoryHooks {
Expand Down Expand Up @@ -254,9 +255,12 @@ impl ContextModuleFactory {
&self,
context_module_options: &mut ContextModuleOptions,
) -> Result<Option<ModuleFactoryResult>> {
let context_options = &context_module_options.context_options;
let mut after_resolve_result = AfterResolveResult {
resource: context_module_options.resource.to_owned(),
reg_exp: context_module_options.context_options.reg_exp.clone(),
context: context_options.context.to_owned(),
request: context_options.request.to_owned(),
reg_exp: context_options.reg_exp.clone(),
};

if let Some(false) = self
Expand Down
33 changes: 31 additions & 2 deletions crates/rspack_macros/src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use syn::{
parse::{Parse, ParseStream},
punctuated::Punctuated,
token::Comma,
Error, Ident, LitStr, PatType, Result, Token, TypePath,
Error, Ident, LitStr, PatType, Result, Token, Type, TypePath,
};

pub struct DefineHookInput {
Expand All @@ -29,6 +29,18 @@ impl Parse for DefineHookInput {
"SyncSeriesBail" => ExecKind::SyncSeriesBail {
ret: ExecKind::parse_ret(input)?,
},
"AsyncSeriesWaterfall" => {
let ret = match ExecKind::parse_ret(input)? {
Some(t) => t,
None => {
return Err(Error::new(
input.span(),
"Waterfall hooks must explicitly define a return type",
))
}
};
ExecKind::AsyncSeriesWaterfall { ret }
}
"AsyncSeries" => ExecKind::AsyncSeries,
"AsyncParallel" => ExecKind::AsyncParallel,
"SyncSeries" => ExecKind::SyncSeries,
Expand Down Expand Up @@ -142,6 +154,7 @@ impl DefineHookInput {
enum ExecKind {
AsyncSeries,
AsyncSeriesBail { ret: Option<TypePath> },
AsyncSeriesWaterfall { ret: TypePath },
AsyncParallel,
SyncSeries,
SyncSeriesBail { ret: Option<TypePath> },
Expand All @@ -160,7 +173,10 @@ impl ExecKind {

pub fn is_async(&self) -> bool {
match self {
Self::AsyncSeries | Self::AsyncSeriesBail { .. } | Self::AsyncParallel => true,
Self::AsyncSeries
| Self::AsyncSeriesBail { .. }
| Self::AsyncSeriesWaterfall { .. }
| Self::AsyncParallel => true,
Self::SyncSeries | Self::SyncSeriesBail { .. } => false,
}
}
Expand All @@ -174,6 +190,9 @@ impl ExecKind {
quote! { rspack_hook::__macro_helper::Result<std::option::Option<()>> }
}
}
Self::AsyncSeriesWaterfall { ret } => {
quote! { rspack_hook::__macro_helper::Result<#ret> }
}
_ => quote! { rspack_hook::__macro_helper::Result<()> },
}
}
Expand Down Expand Up @@ -219,6 +238,16 @@ impl ExecKind {
Ok(None)
}
}
Self::AsyncSeriesWaterfall { .. } => {
quote! {
#additional_taps
let mut data = #args;
for tap in all_taps {
data = tap.run(data).await?;
}
Ok(data)
}
}
Self::AsyncParallel => {
quote! {
#additional_taps
Expand Down
16 changes: 9 additions & 7 deletions packages/rspack/src/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { assertNotNill } from "./util/assertNotNil";
import { FileSystemInfoEntry } from "./FileSystemInfo";
import { RuntimeGlobals } from "./RuntimeGlobals";
import { tryRunOrWebpackError } from "./lib/HookWebpackError";
import { CodeGenerationResult, ContextModuleFactoryResolveData, Module, ResolveData } from "./Module";
import { CodeGenerationResult, ContextModuleFactoryAfterResolveArgs, Module, ResolveData } from "./Module";
import { canInherentFromParent } from "./builtin-plugin/base";
import ExecuteModulePlugin from "./ExecuteModulePlugin";
import { Chunk } from "./Chunk";
Expand Down Expand Up @@ -510,7 +510,7 @@ class Compiler {
createData: arg.createData
};
const ret = await queried.promise(data);
return [ret, data.createData];
return [!!ret, ret];
}
),
registerNormalModuleFactoryCreateModuleTaps: this.#createHookRegisterTaps(
Expand Down Expand Up @@ -547,19 +547,21 @@ class Compiler {
binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve,
() => this.compilationParams!.contextModuleFactory.hooks.afterResolve,
queried => async (args: binding.JsContextModuleFactoryAfterResolveArgs) => {
const resolveData: ContextModuleFactoryResolveData = {
const resolveData: ContextModuleFactoryAfterResolveArgs = {
resource: args.resource,
regExp: args.regExp ? new RegExp(args.regExp) : undefined
// request: arg.request,
// context: arg.context,
regExp: args.regExp ? new RegExp(args.regExp) : undefined,
// request: args.request,
// context: args.context,
// fileDependencies: arg.fileDependencies,
// missingDependencies: arg.missingDependencies,
// contextDependencies: arg.contextDependencies,
// createData: arg.createData
};
const raw = await queried.promise(resolveData);
const result = raw ? {
const result = raw !== undefined ? {
resource: raw.resource,
context: '',
request: '',
regExp: raw.regExp?.toString()
} satisfies binding.JsContextModuleFactoryAfterResolveArgs : undefined;
return [!!raw, result];
Expand Down
6 changes: 3 additions & 3 deletions packages/rspack/src/ContextModuleFactory.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as liteTapable from "./lite-tapable";
import { ContextModuleFactoryResolveData, ResolveData } from "./Module";
import { ContextModuleFactoryAfterResolveArgs, ResolveData } from "./Module";

export class ContextModuleFactory {
hooks: {
// TODO: second param resolveData
// resolveForScheme: HookMap<
// AsyncSeriesBailHook<[ResourceDataWithData], true | void>
// >;
beforeResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>;
afterResolve: liteTapable.AsyncSeriesBailHook<[ContextModuleFactoryResolveData], false | void | ContextModuleFactoryResolveData>;
beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ResolveData], false | void>;
afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveArgs], false | void | ContextModuleFactoryAfterResolveArgs>;
};
constructor() {
this.hooks = {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/src/Module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type ResolveData = {
createData?: CreateData;
};

export type ContextModuleFactoryResolveData = {
export type ContextModuleFactoryAfterResolveArgs = {
resource: string;
regExp?: RegExp;
}
Expand Down
120 changes: 120 additions & 0 deletions packages/rspack/src/lite-tapable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,126 @@ export class AsyncSeriesBailHook<
}
}

export class AsyncSeriesWaterfallHook<
T,
R,
AdditionalOptions = UnsetAdditionalOptions
> extends Hook<T, R, AdditionalOptions> {
constructor(args?: ArgumentNames<AsArray<T>>, name?: string) {
if (!args?.length)
throw new Error("Waterfall hooks must have at least one argument");
super(args, name);
}

callAsyncStageRange(
queried: QueriedHook<T, R, AdditionalOptions>,
...args: Append<AsArray<T>, Callback<Error, R>>
) {
const {
stageRange: [from, to],
tapsInRange
} = queried;
const args2 = [...args];
const cb = args2.pop() as Callback<Error, R>;
if (from === minStage) {
this._runCallInterceptors(...args2);
}
const done = () => {
this._runDoneInterceptors();
cb(null);
};
const error = (e: Error) => {
this._runErrorInterceptors(e);
cb(e);
};
const result = (r: R) => {
this._runResultInterceptors(r);
cb(null, r);
};
if (tapsInRange.length === 0) return done();
let index = 0;
const next = () => {
const tap = tapsInRange[index];
this._runTapInterceptors(tap);
if (tap.type === "promise") {
const promise = tap.fn(...args2);
if (!promise || !promise.then) {
throw new Error(
"Tap function (tapPromise) did not return promise (returned " +
promise +
")"
);
}
promise.then(
(r: R) => {
index += 1;
if (r !== undefined) {
result(r);
} else if (index === tapsInRange.length) {
done();
} else {
next();
}
},
(e: Error) => {
index = tapsInRange.length;
error(e);
}
);
} else if (tap.type === "async") {
tap.fn(...args2, (e: Error, r: R) => {
if (e) {
index = tapsInRange.length;
error(e);
} else {
index += 1;
if (r !== undefined) {
result(r);
} else if (index === tapsInRange.length) {
done();
} else {
next();
}
}
});
} else {
let hasError = false;
let r = undefined;
try {
r = tap.fn(...args2);
} catch (e) {
hasError = true;
index = tapsInRange.length;
error(e as Error);
}
if (!hasError) {
index += 1;
if (r !== undefined) {
result(r);
} else if (index === tapsInRange.length) {
done();
} else {
next();
}
}
}
if (index === tapsInRange.length) return;
};
next();
}

tapAsync(
options: Options<AdditionalOptions>,
fn: FnWithCallback<T, void>
): void {
this._tap("async", options, fn);
}

tapPromise(options: Options<AdditionalOptions>, fn: Fn<T, void>): void {
this._tap("promise", options, fn);
}
}

const defaultFactory = (key: HookMapKey, hook: unknown) => hook;

export type HookMapKey = any;
Expand Down

0 comments on commit 7ea5bec

Please sign in to comment.