From b03a5081dcad9eb279f1b80193022b77a0b6d2bf Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Tue, 30 Apr 2024 16:24:17 +0800 Subject: [PATCH 01/12] fix: contextModuleFactory afterResolve hook --- Cargo.lock | 1 + crates/node_binding/Cargo.toml | 1 + crates/node_binding/binding.d.ts | 5 + .../node_binding/src/plugins/interceptor.rs | 98 ++++++++----------- .../src/context_module_factory.rs | 10 ++ crates/rspack_binding_values/src/lib.rs | 2 + crates/rspack_core/src/context_module.rs | 2 +- .../rspack_core/src/context_module_factory.rs | 98 +++++++++++++++---- packages/rspack/src/Compiler.ts | 22 +++-- packages/rspack/src/ContextModuleFactory.ts | 4 +- packages/rspack/src/Module.ts | 5 + 11 files changed, 159 insertions(+), 89 deletions(-) create mode 100644 crates/rspack_binding_values/src/context_module_factory.rs diff --git a/Cargo.lock b/Cargo.lock index d85374cf1c9..a3969f3e4b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3103,6 +3103,7 @@ dependencies = [ "rspack_hook", "rspack_identifier", "rspack_napi", + "rspack_regex", "rspack_tracing", "tokio", "tracing", diff --git a/crates/node_binding/Cargo.toml b/crates/node_binding/Cargo.toml index f3c6877b463..cd82e107569 100644 --- a/crates/node_binding/Cargo.toml +++ b/crates/node_binding/Cargo.toml @@ -24,6 +24,7 @@ rspack_hook = { path = "../rspack_hook" } rspack_identifier = { path = "../rspack_identifier" } rspack_napi = { path = "../rspack_napi" } rspack_tracing = { path = "../rspack_tracing" } +rspack_regex = { path = "../rspack_regex" } tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } async-trait = { workspace = true } diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 44ee00778d6..3f44d2552fa 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -291,6 +291,11 @@ export interface JsCompatSource { map?: Buffer } +export interface JsContextModuleFactoryAfterResolveArgs { + resource: string + regExp?: string +} + export interface JsCreateData { request: string userRequest: string diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index 8ee1962d446..6416d3febcf 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -11,37 +11,40 @@ use napi::{ }; use rspack_binding_values::{ CompatSource, JsAfterResolveData, JsAfterResolveOutput, JsAssetEmittedArgs, JsBeforeResolveArgs, - JsBeforeResolveOutput, JsChunk, JsChunkAssetArgs, JsCompilation, JsCreateData, + JsBeforeResolveOutput, JsChunk, JsChunkAssetArgs, JsCompilation, + JsContextModuleFactoryAfterResolveArgs, JsContextModuleFactoryAfterResolveResult, JsCreateData, JsExecuteModuleArg, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, JsResolveForSchemeOutput, JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, }; use rspack_core::{ - rspack_sources::SourceExt, AssetEmittedInfo, BoxModule, Chunk, ChunkUkey, CodeGenerationResults, - Compilation, CompilationAfterOptimizeModules, CompilationAfterOptimizeModulesHook, - CompilationAfterProcessAssets, CompilationAfterProcessAssetsHook, CompilationAfterSeal, - CompilationAfterSealHook, CompilationBuildModule, CompilationBuildModuleHook, - CompilationChunkAsset, CompilationChunkAssetHook, CompilationExecuteModule, - CompilationExecuteModuleHook, CompilationFinishModules, CompilationFinishModulesHook, - CompilationOptimizeChunkModules, CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, - CompilationOptimizeModulesHook, CompilationOptimizeTree, CompilationOptimizeTreeHook, - CompilationParams, CompilationProcessAssets, CompilationProcessAssetsHook, - CompilationRuntimeModule, CompilationRuntimeModuleHook, CompilationStillValidModule, - CompilationStillValidModuleHook, CompilationSucceedModule, CompilationSucceedModuleHook, - CompilerAfterEmit, CompilerAfterEmitHook, CompilerAssetEmitted, CompilerAssetEmittedHook, - CompilerCompilation, CompilerCompilationHook, CompilerEmit, CompilerEmitHook, CompilerFinishMake, - CompilerFinishMakeHook, CompilerMake, CompilerMakeHook, CompilerShouldEmit, - CompilerShouldEmitHook, CompilerThisCompilation, CompilerThisCompilationHook, - ContextModuleFactoryAfterResolve, ContextModuleFactoryAfterResolveHook, - ContextModuleFactoryBeforeResolve, ContextModuleFactoryBeforeResolveHook, ExecuteModuleId, - MakeParam, ModuleFactoryCreateData, ModuleIdentifier, NormalModuleCreateData, - NormalModuleFactoryAfterResolve, NormalModuleFactoryAfterResolveHook, - NormalModuleFactoryBeforeResolve, NormalModuleFactoryBeforeResolveHook, - NormalModuleFactoryCreateModule, NormalModuleFactoryCreateModuleHook, - NormalModuleFactoryResolveForScheme, NormalModuleFactoryResolveForSchemeHook, ResourceData, + rspack_sources::SourceExt, AfterResolveResult, AssetEmittedInfo, BoxModule, Chunk, ChunkUkey, + CodeGenerationResults, Compilation, CompilationAfterOptimizeModules, + CompilationAfterOptimizeModulesHook, CompilationAfterProcessAssets, + CompilationAfterProcessAssetsHook, CompilationAfterSeal, CompilationAfterSealHook, + CompilationBuildModule, CompilationBuildModuleHook, CompilationChunkAsset, + CompilationChunkAssetHook, CompilationExecuteModule, CompilationExecuteModuleHook, + CompilationFinishModules, CompilationFinishModulesHook, CompilationOptimizeChunkModules, + CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, CompilationOptimizeModulesHook, + CompilationOptimizeTree, CompilationOptimizeTreeHook, CompilationParams, + CompilationProcessAssets, CompilationProcessAssetsHook, CompilationRuntimeModule, + CompilationRuntimeModuleHook, CompilationStillValidModule, CompilationStillValidModuleHook, + CompilationSucceedModule, CompilationSucceedModuleHook, CompilerAfterEmit, CompilerAfterEmitHook, + CompilerAssetEmitted, CompilerAssetEmittedHook, CompilerCompilation, CompilerCompilationHook, + CompilerEmit, CompilerEmitHook, CompilerFinishMake, CompilerFinishMakeHook, CompilerMake, + CompilerMakeHook, CompilerShouldEmit, CompilerShouldEmitHook, CompilerThisCompilation, + CompilerThisCompilationHook, ContextModuleFactoryAfterResolve, + ContextModuleFactoryAfterResolveHook, ContextModuleFactoryBeforeResolve, + ContextModuleFactoryBeforeResolveHook, ExecuteModuleId, MakeParam, ModuleFactoryCreateData, + ModuleIdentifier, NormalModuleCreateData, NormalModuleFactoryAfterResolve, + NormalModuleFactoryAfterResolveHook, NormalModuleFactoryBeforeResolve, + NormalModuleFactoryBeforeResolveHook, NormalModuleFactoryCreateModule, + NormalModuleFactoryCreateModuleHook, NormalModuleFactoryResolveForScheme, + NormalModuleFactoryResolveForSchemeHook, ResourceData, }; use rspack_hook::{Hook, Interceptor}; use rspack_identifier::IdentifierSet; use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_regex::RspackRegex; #[napi(object)] pub struct JsTap { @@ -441,8 +444,10 @@ pub struct RegisterJsTaps { #[napi( ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise); stage: number; }>" )] - pub register_context_module_factory_after_resolve_taps: - RegisterFunction>>, + pub register_context_module_factory_after_resolve_taps: RegisterFunction< + JsContextModuleFactoryAfterResolveArgs, + Promise, + >, } /* Compiler Hooks */ @@ -670,7 +675,7 @@ define_register!( ); define_register!( RegisterContextModuleFactoryAfterResolveTaps, - tap = ContextModuleFactoryAfterResolveTap>> @ ContextModuleFactoryAfterResolveHook, + tap = ContextModuleFactoryAfterResolveTap> @ ContextModuleFactoryAfterResolveHook, cache = true, sync = false, kind = RegisterJsTapKind::ContextModuleFactoryAfterResolve, @@ -1231,37 +1236,20 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap #[async_trait] impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap { - async fn run(&self, data: &mut ModuleFactoryCreateData) -> rspack_error::Result> { - let dependency = data - .dependency - .as_context_dependency_mut() - .expect("should be context dependency"); - self + async fn run(&self, result: &mut AfterResolveResult) -> rspack_error::Result> { + let (ret, res) = self .function - .call_with_promise(JsAfterResolveData { - request: dependency.request().to_string(), - context: data.context.to_string(), - file_dependencies: data - .file_dependencies - .clone() - .into_iter() - .map(|item| item.to_string_lossy().to_string()) - .collect::>(), - context_dependencies: data - .context_dependencies - .clone() - .into_iter() - .map(|item| item.to_string_lossy().to_string()) - .collect::>(), - missing_dependencies: data - .missing_dependencies - .clone() - .into_iter() - .map(|item| item.to_string_lossy().to_string()) - .collect::>(), - create_data: None, + .call_with_promise(JsContextModuleFactoryAfterResolveArgs { + resource: result.resource.to_owned(), + reg_exp: result.reg_exp.clone().map(|r| r.to_string()), }) - .await + .await?; + result.resource = res.resource; + result.reg_exp = match res.reg_exp { + Some(r) => Some(RspackRegex::new(&r)?), + None => None, + }; + Ok(ret) } fn stage(&self) -> i32 { diff --git a/crates/rspack_binding_values/src/context_module_factory.rs b/crates/rspack_binding_values/src/context_module_factory.rs new file mode 100644 index 00000000000..ab2ac6b1260 --- /dev/null +++ b/crates/rspack_binding_values/src/context_module_factory.rs @@ -0,0 +1,10 @@ +use napi_derive::napi; + +#[napi(object)] +pub struct JsContextModuleFactoryAfterResolveArgs { + pub resource: String, + pub reg_exp: Option, +} + +pub type JsContextModuleFactoryAfterResolveResult = + (Option, JsContextModuleFactoryAfterResolveArgs); diff --git a/crates/rspack_binding_values/src/lib.rs b/crates/rspack_binding_values/src/lib.rs index 576f8ab07b7..dd35fc923b4 100644 --- a/crates/rspack_binding_values/src/lib.rs +++ b/crates/rspack_binding_values/src/lib.rs @@ -5,6 +5,7 @@ mod chunk_graph; mod chunk_group; mod codegen_result; mod compilation; +mod context_module_factory; mod filename; mod module; mod normal_module_factory; @@ -19,6 +20,7 @@ pub use chunk_graph::*; pub use chunk_group::*; pub use codegen_result::*; pub use compilation::*; +pub use context_module_factory::*; pub use filename::*; pub use module::*; pub use normal_module_factory::*; diff --git a/crates/rspack_core/src/context_module.rs b/crates/rspack_core/src/context_module.rs index b52f8c761e4..eb4be255cd5 100644 --- a/crates/rspack_core/src/context_module.rs +++ b/crates/rspack_core/src/context_module.rs @@ -151,7 +151,7 @@ pub struct ContextOptions { pub end: u32, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct ContextModuleOptions { pub addon: String, pub resource: String, diff --git a/crates/rspack_core/src/context_module_factory.rs b/crates/rspack_core/src/context_module_factory.rs index 5db1fd09a1b..634d7739037 100644 --- a/crates/rspack_core/src/context_module_factory.rs +++ b/crates/rspack_core/src/context_module_factory.rs @@ -2,17 +2,42 @@ use std::sync::Arc; use rspack_error::{error, Result}; use rspack_hook::define_hook; +use rspack_regex::RspackRegex; use tracing::instrument; use crate::{ - cache::Cache, resolve, BoxModule, ContextModule, ContextModuleOptions, DependencyCategory, - ModuleExt, ModuleFactory, ModuleFactoryCreateData, ModuleFactoryResult, ModuleIdentifier, - RawModule, ResolveArgs, ResolveOptionsWithDependencyType, ResolveResult, Resolver, - ResolverFactory, SharedPluginDriver, + cache::Cache, resolve, ContextModule, ContextModuleOptions, DependencyCategory, ModuleExt, + ModuleFactory, ModuleFactoryCreateData, ModuleFactoryResult, ModuleIdentifier, RawModule, + ResolveArgs, ResolveOptionsWithDependencyType, ResolveResult, Resolver, ResolverFactory, + SharedPluginDriver, }; +pub struct AfterResolveResult { + pub resource: String, + // context: Context, + // dependencies + // layer + // resolve_options + // file_dependencies: HashSet, + // missing_dependencies: HashSet, + // context_dependencies: HashSet, + // request: String, + // mode + // recursive: bool, + pub reg_exp: Option, + // namespace_object + // addon: String, + // chunk_name: String, + // include + // exclude + // group_options + // type_prefix: String, + // category: String, + // referenced_exports +} + define_hook!(ContextModuleFactoryBeforeResolve: AsyncSeriesBail(data: &mut ModuleFactoryCreateData) -> bool); -define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesBail(data: &mut ModuleFactoryCreateData) -> bool); +define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesBail(data: &mut AfterResolveResult) -> bool); #[derive(Debug, Default)] pub struct ContextModuleFactoryHooks { @@ -35,10 +60,12 @@ impl ModuleFactory for ContextModuleFactory { return Ok(before_resolve_result); } - let factorize_result = self.resolve(data).await?; + let (factorize_result, mut context_module_options) = self.resolve(data).await?; - if let Some(false) = self.after_resolve(data).await? { - return Ok(ModuleFactoryResult::default()); + if let Some(context_module_options) = context_module_options.as_mut() { + if let Some(factorize_result) = self.after_resolve(context_module_options).await? { + return Ok(factorize_result); + } } Ok(factorize_result) @@ -87,7 +114,10 @@ impl ContextModuleFactory { }) } - async fn resolve(&self, data: &mut ModuleFactoryCreateData) -> Result { + async fn resolve( + &self, + data: &mut ModuleFactoryCreateData, + ) -> Result<(ModuleFactoryResult, Option)> { let plugin_driver = &self.plugin_driver; let dependency = data .dependency @@ -175,18 +205,23 @@ impl ContextModuleFactory { Err(err) => (Err(err), false), }; + let mut context_module_options = None; let module = match resource_data { - Ok(ResolveResult::Resource(resource)) => Box::new(ContextModule::new( - ContextModuleOptions { + Ok(ResolveResult::Resource(resource)) => { + let options = ContextModuleOptions { addon: loader_request.to_string(), resource: resource.path.to_string_lossy().to_string(), resource_query: resource.query, resource_fragment: resource.fragment, resolve_options: data.resolve_options.clone(), context_options: dependency.options().clone(), - }, - plugin_driver.resolver_factory.clone(), - )) as BoxModule, + }; + context_module_options = Some(options.clone()); + Box::new(ContextModule::new( + options, + plugin_driver.resolver_factory.clone(), + )) + } Ok(ResolveResult::Ignored) => { let ident = format!("{}/{}", data.context, specifier); let module_identifier = ModuleIdentifier::from(format!("ignored|{ident}")); @@ -197,7 +232,7 @@ impl ContextModuleFactory { Default::default(), ) .boxed(); - return Ok(ModuleFactoryResult::new_with_module(raw_module)); + return Ok((ModuleFactoryResult::new_with_module(raw_module), None)); } Err(err) => { return Err(err); @@ -208,18 +243,39 @@ impl ContextModuleFactory { data.add_missing_dependencies(missing_dependencies); // data.add_context_dependencies(context_dependencies); - Ok(ModuleFactoryResult { + let module_factory_result = ModuleFactoryResult { module: Some(module), from_cache, - }) + }; + Ok((module_factory_result, context_module_options)) } - async fn after_resolve(&self, data: &mut ModuleFactoryCreateData) -> Result> { - self + async fn after_resolve( + &self, + context_module_options: &mut ContextModuleOptions, + ) -> Result> { + let mut after_resolve_result = AfterResolveResult { + resource: context_module_options.resource.to_owned(), + reg_exp: context_module_options.context_options.reg_exp.clone(), + }; + + if let Some(false) = self .plugin_driver .context_module_factory_hooks .after_resolve - .call(data) - .await + .call(&mut after_resolve_result) + .await? + { + return Ok(None); + } + + context_module_options.resource = after_resolve_result.resource; + context_module_options.context_options.reg_exp = after_resolve_result.reg_exp; + + let module = ContextModule::new( + context_module_options.clone(), + self.loader_resolver_factory.clone(), + ); + Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module)))) } } diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index 92a3d872108..de2667fb3d7 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -47,7 +47,7 @@ import { assertNotNill } from "./util/assertNotNil"; import { FileSystemInfoEntry } from "./FileSystemInfo"; import { RuntimeGlobals } from "./RuntimeGlobals"; import { tryRunOrWebpackError } from "./lib/HookWebpackError"; -import { CodeGenerationResult, Module, ResolveData } from "./Module"; +import { CodeGenerationResult, ContextModuleFactoryResolveData, Module, ResolveData } from "./Module"; import { canInherentFromParent } from "./builtin-plugin/base"; import ExecuteModulePlugin from "./ExecuteModulePlugin"; import { Chunk } from "./Chunk"; @@ -546,16 +546,18 @@ class Compiler { this.#createHookRegisterTaps( binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve, () => this.compilationParams!.contextModuleFactory.hooks.afterResolve, - queried => async (arg: binding.JsAfterResolveData) => { - const data: ResolveData = { - request: arg.request, - context: arg.context, - fileDependencies: arg.fileDependencies, - missingDependencies: arg.missingDependencies, - contextDependencies: arg.contextDependencies, - createData: arg.createData + queried => async (args: binding.JsContextModuleFactoryAfterResolveArgs) => { + const resolveData: ContextModuleFactoryResolveData = { + resource: args.resource, + regExp: args.regExp ? new RegExp(args.regExp) : undefined + // request: arg.request, + // context: arg.context, + // fileDependencies: arg.fileDependencies, + // missingDependencies: arg.missingDependencies, + // contextDependencies: arg.contextDependencies, + // createData: arg.createData }; - return await queried.promise(data); + return await queried.promise(resolveData); } ) }; diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index 5c9bebdd9b9..b1bb2013065 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -1,5 +1,5 @@ import * as liteTapable from "./lite-tapable"; -import { ResolveData } from "./Module"; +import { ContextModuleFactoryResolveData, ResolveData } from "./Module"; export class ContextModuleFactory { hooks: { @@ -8,7 +8,7 @@ export class ContextModuleFactory { // AsyncSeriesBailHook<[ResourceDataWithData], true | void> // >; beforeResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>; - afterResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>; + afterResolve: liteTapable.AsyncSeriesBailHook<[ContextModuleFactoryResolveData], false | void>; }; constructor() { this.hooks = { diff --git a/packages/rspack/src/Module.ts b/packages/rspack/src/Module.ts index a17639df4eb..9345cf5ad99 100644 --- a/packages/rspack/src/Module.ts +++ b/packages/rspack/src/Module.ts @@ -26,6 +26,11 @@ export type ResolveData = { createData?: CreateData; }; +export type ContextModuleFactoryResolveData = { + resource: string; + regExp?: RegExp; +} + export class Module { #inner: JsModule; _originalSource?: Source; From adda72807369b76100aa75daf48ec014fa6873da Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Tue, 30 Apr 2024 16:46:53 +0800 Subject: [PATCH 02/12] fix: js side logic --- packages/rspack/src/Compiler.ts | 7 ++++++- packages/rspack/src/ContextModuleFactory.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index de2667fb3d7..e693de47709 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -557,7 +557,12 @@ class Compiler { // contextDependencies: arg.contextDependencies, // createData: arg.createData }; - return await queried.promise(resolveData); + const raw = await queried.promise(resolveData); + const result = raw ? { + resource: raw.resource, + regExp: raw.regExp?.toString() + } satisfies binding.JsContextModuleFactoryAfterResolveArgs : undefined; + return [!!raw, result]; } ) }; diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index b1bb2013065..33410b53687 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -8,7 +8,7 @@ export class ContextModuleFactory { // AsyncSeriesBailHook<[ResourceDataWithData], true | void> // >; beforeResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>; - afterResolve: liteTapable.AsyncSeriesBailHook<[ContextModuleFactoryResolveData], false | void>; + afterResolve: liteTapable.AsyncSeriesBailHook<[ContextModuleFactoryResolveData], false | void | ContextModuleFactoryResolveData>; }; constructor() { this.hooks = { From c693c7ae9da5767e15f4462853db4927d56aa965 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 17:34:53 +0800 Subject: [PATCH 03/12] fix: afterResolve in ContextModuleFactory should be AsyncSeriesWaterfallHook --- crates/node_binding/binding.d.ts | 4 +- .../node_binding/src/plugins/interceptor.rs | 40 +++--- .../src/context_module_factory.rs | 7 +- .../rspack_core/src/context_module_factory.rs | 50 ++++---- crates/rspack_macros/src/hook.rs | 33 ++++- packages/rspack/src/Compiler.ts | 28 ++-- packages/rspack/src/ContextModuleFactory.ts | 6 +- packages/rspack/src/Module.ts | 4 +- packages/rspack/src/lite-tapable/index.ts | 120 ++++++++++++++++++ 9 files changed, 230 insertions(+), 62 deletions(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 3f44d2552fa..724fb7b46e3 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -291,8 +291,10 @@ export interface JsCompatSource { map?: Buffer } -export interface JsContextModuleFactoryAfterResolveArgs { +export interface JsContextModuleFactoryAfterResolveResult { resource: string + context: string + request: string regExp?: string } diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index 6416d3febcf..dd2625316c2 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -12,9 +12,9 @@ use napi::{ use rspack_binding_values::{ CompatSource, JsAfterResolveData, JsAfterResolveOutput, JsAssetEmittedArgs, JsBeforeResolveArgs, JsBeforeResolveOutput, JsChunk, JsChunkAssetArgs, JsCompilation, - JsContextModuleFactoryAfterResolveArgs, JsContextModuleFactoryAfterResolveResult, JsCreateData, - JsExecuteModuleArg, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, - JsResolveForSchemeOutput, JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, + JsContextModuleFactoryAfterResolveResult, JsCreateData, JsExecuteModuleArg, JsModule, + JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, JsResolveForSchemeOutput, + JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, }; use rspack_core::{ rspack_sources::SourceExt, AfterResolveResult, AssetEmittedInfo, BoxModule, Chunk, ChunkUkey, @@ -445,8 +445,8 @@ pub struct RegisterJsTaps { ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise); stage: number; }>" )] pub register_context_module_factory_after_resolve_taps: RegisterFunction< - JsContextModuleFactoryAfterResolveArgs, - Promise, + JsContextModuleFactoryAfterResolveResult, + Promise>, >, } @@ -675,7 +675,7 @@ define_register!( ); define_register!( RegisterContextModuleFactoryAfterResolveTaps, - tap = ContextModuleFactoryAfterResolveTap> @ ContextModuleFactoryAfterResolveHook, + tap = ContextModuleFactoryAfterResolveTap>> @ ContextModuleFactoryAfterResolveHook, cache = true, sync = false, kind = RegisterJsTapKind::ContextModuleFactoryAfterResolve, @@ -1236,20 +1236,30 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap #[async_trait] impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap { - async fn run(&self, result: &mut AfterResolveResult) -> rspack_error::Result> { - let (ret, res) = self + async fn run( + &self, + mut result: AfterResolveResult, + ) -> rspack_error::Result> { + let js_result = self .function - .call_with_promise(JsContextModuleFactoryAfterResolveArgs { + .call_with_promise(JsContextModuleFactoryAfterResolveResult { 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 { - Some(r) => Some(RspackRegex::new(&r)?), - None => None, - }; - Ok(ret) + match js_result { + Some(js_result) => { + result.resource = js_result.resource; + result.reg_exp = match js_result.reg_exp { + Some(r) => Some(RspackRegex::new(&r)?), + None => None, + }; + Ok(Some(result)) + } + None => Ok(None), + } } fn stage(&self) -> i32 { diff --git a/crates/rspack_binding_values/src/context_module_factory.rs b/crates/rspack_binding_values/src/context_module_factory.rs index ab2ac6b1260..5dd74d5a2a3 100644 --- a/crates/rspack_binding_values/src/context_module_factory.rs +++ b/crates/rspack_binding_values/src/context_module_factory.rs @@ -1,10 +1,9 @@ use napi_derive::napi; #[napi(object)] -pub struct JsContextModuleFactoryAfterResolveArgs { +pub struct JsContextModuleFactoryAfterResolveResult { pub resource: String, + pub context: String, + pub request: String, pub reg_exp: Option, } - -pub type JsContextModuleFactoryAfterResolveResult = - (Option, JsContextModuleFactoryAfterResolveArgs); diff --git a/crates/rspack_core/src/context_module_factory.rs b/crates/rspack_core/src/context_module_factory.rs index 634d7739037..0b2e8fe61e3 100644 --- a/crates/rspack_core/src/context_module_factory.rs +++ b/crates/rspack_core/src/context_module_factory.rs @@ -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, // missing_dependencies: HashSet, // context_dependencies: HashSet, - // request: String, + pub request: String, // mode // recursive: bool, pub reg_exp: Option, @@ -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) -> Option); #[derive(Debug, Default)] pub struct ContextModuleFactoryHooks { @@ -205,8 +206,7 @@ impl ContextModuleFactory { Err(err) => (Err(err), false), }; - let mut context_module_options = None; - let module = match resource_data { + let (module, context_module_options) = match resource_data { Ok(ResolveResult::Resource(resource)) => { let options = ContextModuleOptions { addon: loader_request.to_string(), @@ -216,11 +216,11 @@ impl ContextModuleFactory { resolve_options: data.resolve_options.clone(), context_options: dependency.options().clone(), }; - context_module_options = Some(options.clone()); - Box::new(ContextModule::new( - options, + let module = Box::new(ContextModule::new( + options.clone(), plugin_driver.resolver_factory.clone(), - )) + )); + (module, Some(options)) } Ok(ResolveResult::Ignored) => { let ident = format!("{}/{}", data.context, specifier); @@ -254,28 +254,32 @@ impl ContextModuleFactory { &self, context_module_options: &mut ContextModuleOptions, ) -> Result> { - let mut after_resolve_result = AfterResolveResult { + let context_options = &context_module_options.context_options; + let 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 + match self .plugin_driver .context_module_factory_hooks .after_resolve - .call(&mut after_resolve_result) + .call(after_resolve_result) .await? { - return Ok(None); - } - - context_module_options.resource = after_resolve_result.resource; - context_module_options.context_options.reg_exp = after_resolve_result.reg_exp; + Some(after_resolve_result) => { + context_module_options.resource = after_resolve_result.resource; + context_module_options.context_options.reg_exp = after_resolve_result.reg_exp; - let module = ContextModule::new( - context_module_options.clone(), - self.loader_resolver_factory.clone(), - ); - Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module)))) + let module = ContextModule::new( + context_module_options.clone(), + self.loader_resolver_factory.clone(), + ); + Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module)))) + } + None => Ok(None), + } } } diff --git a/crates/rspack_macros/src/hook.rs b/crates/rspack_macros/src/hook.rs index ce6e97ad03a..7a8295c0169 100644 --- a/crates/rspack_macros/src/hook.rs +++ b/crates/rspack_macros/src/hook.rs @@ -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, @@ -142,6 +154,7 @@ impl DefineHookInput { enum ExecKind { AsyncSeries, AsyncSeriesBail { ret: Option }, + AsyncSeriesWaterfall { ret: TypePath }, AsyncParallel, SyncSeries, SyncSeriesBail { ret: Option }, @@ -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, } } @@ -174,6 +190,9 @@ impl ExecKind { quote! { rspack_hook::__macro_helper::Result> } } } + Self::AsyncSeriesWaterfall { ret } => { + quote! { rspack_hook::__macro_helper::Result<#ret> } + } _ => quote! { rspack_hook::__macro_helper::Result<()> }, } } @@ -219,6 +238,18 @@ impl ExecKind { Ok(None) } } + Self::AsyncSeriesWaterfall { .. } => { + quote! { + #additional_taps + let mut data = #args; + for tap in all_taps { + if let Some(res) = tap.run(data.clone()).await? { + data = res; + } + } + Ok(Some(data)) + } + } Self::AsyncParallel => { quote! { #additional_taps diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index e693de47709..9ee4ccc2084 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -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, ContextModuleFactoryAfterResolveResult, Module, ResolveData } from "./Module"; import { canInherentFromParent } from "./builtin-plugin/base"; import ExecuteModulePlugin from "./ExecuteModulePlugin"; import { Chunk } from "./Chunk"; @@ -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( @@ -546,23 +546,23 @@ class Compiler { this.#createHookRegisterTaps( binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve, () => this.compilationParams!.contextModuleFactory.hooks.afterResolve, - queried => async (args: binding.JsContextModuleFactoryAfterResolveArgs) => { - const resolveData: ContextModuleFactoryResolveData = { + queried => async (args: binding.JsContextModuleFactoryAfterResolveResult) => { + const resolveData: ContextModuleFactoryAfterResolveResult = { resource: args.resource, - regExp: args.regExp ? new RegExp(args.regExp) : undefined - // request: arg.request, - // context: arg.context, - // fileDependencies: arg.fileDependencies, - // missingDependencies: arg.missingDependencies, - // contextDependencies: arg.contextDependencies, - // createData: arg.createData + regExp: args.regExp ? new RegExp(args.regExp) : undefined, + request: args.request, + context: args.context, }; const raw = await queried.promise(resolveData); const result = raw ? { resource: raw.resource, - regExp: raw.regExp?.toString() - } satisfies binding.JsContextModuleFactoryAfterResolveArgs : undefined; - return [!!raw, result]; + context: '', + request: '', + regExp: raw.regExp?.toString(), + // TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin. + dependencies: [], + } : undefined; + return result; } ) }; diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index 33410b53687..1075b64baa0 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -1,5 +1,5 @@ import * as liteTapable from "./lite-tapable"; -import { ContextModuleFactoryResolveData, ResolveData } from "./Module"; +import { ContextModuleFactoryAfterResolveResult, ResolveData } from "./Module"; export class ContextModuleFactory { hooks: { @@ -7,8 +7,8 @@ export class ContextModuleFactory { // 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<[ContextModuleFactoryAfterResolveResult], false | void | ContextModuleFactoryAfterResolveResult>; }; constructor() { this.hooks = { diff --git a/packages/rspack/src/Module.ts b/packages/rspack/src/Module.ts index 9345cf5ad99..775d28e5629 100644 --- a/packages/rspack/src/Module.ts +++ b/packages/rspack/src/Module.ts @@ -26,8 +26,10 @@ export type ResolveData = { createData?: CreateData; }; -export type ContextModuleFactoryResolveData = { +export type ContextModuleFactoryAfterResolveResult = { resource: string; + context: string + request: string regExp?: RegExp; } diff --git a/packages/rspack/src/lite-tapable/index.ts b/packages/rspack/src/lite-tapable/index.ts index 902f91e87e5..a785266a8a6 100644 --- a/packages/rspack/src/lite-tapable/index.ts +++ b/packages/rspack/src/lite-tapable/index.ts @@ -772,6 +772,126 @@ export class AsyncSeriesBailHook< } } +export class AsyncSeriesWaterfallHook< + T, + R, + AdditionalOptions = UnsetAdditionalOptions +> extends Hook { + constructor(args?: ArgumentNames>, name?: string) { + if (!args?.length) + throw new Error("Waterfall hooks must have at least one argument"); + super(args, name); + } + + callAsyncStageRange( + queried: QueriedHook, + ...args: Append, Callback> + ) { + const { + stageRange: [from, to], + tapsInRange + } = queried; + const args2 = [...args]; + const cb = args2.pop() as Callback; + 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, + fn: FnWithCallback + ): void { + this._tap("async", options, fn); + } + + tapPromise(options: Options, fn: Fn): void { + this._tap("promise", options, fn); + } +} + const defaultFactory = (key: HookMapKey, hook: unknown) => hook; export type HookMapKey = any; From 7d5b7c52d7ac0f3f9f75ee1e239c6f252a1791a9 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 20:00:29 +0800 Subject: [PATCH 04/12] fix: refactor context module factory hooks --- .../node_binding/src/plugins/interceptor.rs | 145 +++++++++--------- .../src/context_module_factory.rs | 15 +- .../rspack_core/src/context_module_factory.rs | 65 ++++++-- crates/rspack_macros/src/hook.rs | 6 +- crates/rspack_plugin_ignore/src/lib.rs | 29 ++-- 5 files changed, 158 insertions(+), 102 deletions(-) diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index dd2625316c2..b653cb69523 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -12,34 +12,35 @@ use napi::{ use rspack_binding_values::{ CompatSource, JsAfterResolveData, JsAfterResolveOutput, JsAssetEmittedArgs, JsBeforeResolveArgs, JsBeforeResolveOutput, JsChunk, JsChunkAssetArgs, JsCompilation, - JsContextModuleFactoryAfterResolveResult, JsCreateData, JsExecuteModuleArg, JsModule, - JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, JsResolveForSchemeOutput, - JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, + JsContextModuleFactoryAfterResolveData, JsContextModuleFactoryAfterResolveResult, + JsContextModuleFactoryBeforeResolveData, JsContextModuleFactoryBeforeResolveResult, JsCreateData, + JsExecuteModuleArg, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveForSchemeArgs, + JsResolveForSchemeOutput, JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, }; use rspack_core::{ - rspack_sources::SourceExt, AfterResolveResult, AssetEmittedInfo, BoxModule, Chunk, ChunkUkey, - CodeGenerationResults, Compilation, CompilationAfterOptimizeModules, - CompilationAfterOptimizeModulesHook, CompilationAfterProcessAssets, - CompilationAfterProcessAssetsHook, CompilationAfterSeal, CompilationAfterSealHook, - CompilationBuildModule, CompilationBuildModuleHook, CompilationChunkAsset, - CompilationChunkAssetHook, CompilationExecuteModule, CompilationExecuteModuleHook, - CompilationFinishModules, CompilationFinishModulesHook, CompilationOptimizeChunkModules, - CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, CompilationOptimizeModulesHook, - CompilationOptimizeTree, CompilationOptimizeTreeHook, CompilationParams, - CompilationProcessAssets, CompilationProcessAssetsHook, CompilationRuntimeModule, - CompilationRuntimeModuleHook, CompilationStillValidModule, CompilationStillValidModuleHook, - CompilationSucceedModule, CompilationSucceedModuleHook, CompilerAfterEmit, CompilerAfterEmitHook, - CompilerAssetEmitted, CompilerAssetEmittedHook, CompilerCompilation, CompilerCompilationHook, - CompilerEmit, CompilerEmitHook, CompilerFinishMake, CompilerFinishMakeHook, CompilerMake, - CompilerMakeHook, CompilerShouldEmit, CompilerShouldEmitHook, CompilerThisCompilation, - CompilerThisCompilationHook, ContextModuleFactoryAfterResolve, - ContextModuleFactoryAfterResolveHook, ContextModuleFactoryBeforeResolve, - ContextModuleFactoryBeforeResolveHook, ExecuteModuleId, MakeParam, ModuleFactoryCreateData, - ModuleIdentifier, NormalModuleCreateData, NormalModuleFactoryAfterResolve, - NormalModuleFactoryAfterResolveHook, NormalModuleFactoryBeforeResolve, - NormalModuleFactoryBeforeResolveHook, NormalModuleFactoryCreateModule, - NormalModuleFactoryCreateModuleHook, NormalModuleFactoryResolveForScheme, - NormalModuleFactoryResolveForSchemeHook, ResourceData, + rspack_sources::SourceExt, AfterResolveData, AfterResolveResult, AssetEmittedInfo, + BeforeResolveData, BeforeResolveResult, BoxModule, Chunk, ChunkUkey, CodeGenerationResults, + Compilation, CompilationAfterOptimizeModules, CompilationAfterOptimizeModulesHook, + CompilationAfterProcessAssets, CompilationAfterProcessAssetsHook, CompilationAfterSeal, + CompilationAfterSealHook, CompilationBuildModule, CompilationBuildModuleHook, + CompilationChunkAsset, CompilationChunkAssetHook, CompilationExecuteModule, + CompilationExecuteModuleHook, CompilationFinishModules, CompilationFinishModulesHook, + CompilationOptimizeChunkModules, CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, + CompilationOptimizeModulesHook, CompilationOptimizeTree, CompilationOptimizeTreeHook, + CompilationParams, CompilationProcessAssets, CompilationProcessAssetsHook, + CompilationRuntimeModule, CompilationRuntimeModuleHook, CompilationStillValidModule, + CompilationStillValidModuleHook, CompilationSucceedModule, CompilationSucceedModuleHook, + CompilerAfterEmit, CompilerAfterEmitHook, CompilerAssetEmitted, CompilerAssetEmittedHook, + CompilerCompilation, CompilerCompilationHook, CompilerEmit, CompilerEmitHook, CompilerFinishMake, + CompilerFinishMakeHook, CompilerMake, CompilerMakeHook, CompilerShouldEmit, + CompilerShouldEmitHook, CompilerThisCompilation, CompilerThisCompilationHook, + ContextModuleFactoryAfterResolve, ContextModuleFactoryAfterResolveHook, + ContextModuleFactoryBeforeResolve, ContextModuleFactoryBeforeResolveHook, ExecuteModuleId, + MakeParam, ModuleFactoryCreateData, ModuleIdentifier, NormalModuleCreateData, + NormalModuleFactoryAfterResolve, NormalModuleFactoryAfterResolveHook, + NormalModuleFactoryBeforeResolve, NormalModuleFactoryBeforeResolveHook, + NormalModuleFactoryCreateModule, NormalModuleFactoryCreateModuleHook, + NormalModuleFactoryResolveForScheme, NormalModuleFactoryResolveForSchemeHook, ResourceData, }; use rspack_hook::{Hook, Interceptor}; use rspack_identifier::IdentifierSet; @@ -437,16 +438,18 @@ pub struct RegisterJsTaps { pub register_normal_module_factory_create_module_taps: RegisterFunction>, #[napi( - ts_type = "(stages: Array) => Array<{ function: ((arg: JsBeforeResolveArgs) => Promise<[boolean | undefined, JsBeforeResolveArgs]>); stage: number; }>" + ts_type = "(stages: Array) => Array<{ function: ((arg: JsContextModuleFactoryBeforeResolveResult) => Promise); stage: number; }>" )] - pub register_context_module_factory_before_resolve_taps: - RegisterFunction>, + pub register_context_module_factory_before_resolve_taps: RegisterFunction< + JsContextModuleFactoryBeforeResolveResult, + Promise, + >, #[napi( - ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise); stage: number; }>" + ts_type = "(stages: Array) => Array<{ function: ((arg: JsContextModuleFactoryAfterResolveResult) => Promise); stage: number; }>" )] pub register_context_module_factory_after_resolve_taps: RegisterFunction< JsContextModuleFactoryAfterResolveResult, - Promise>, + Promise, >, } @@ -667,7 +670,7 @@ define_register!( /* ContextModuleFactory Hooks */ define_register!( RegisterContextModuleFactoryBeforeResolveTaps, - tap = ContextModuleFactoryBeforeResolveTap> @ ContextModuleFactoryBeforeResolveHook, + tap = ContextModuleFactoryBeforeResolveTap> @ ContextModuleFactoryBeforeResolveHook, cache = true, sync = false, kind = RegisterJsTapKind::ContextModuleFactoryBeforeResolve, @@ -675,7 +678,7 @@ define_register!( ); define_register!( RegisterContextModuleFactoryAfterResolveTaps, - tap = ContextModuleFactoryAfterResolveTap>> @ ContextModuleFactoryAfterResolveHook, + tap = ContextModuleFactoryAfterResolveTap> @ ContextModuleFactoryAfterResolveHook, cache = true, sync = false, kind = RegisterJsTapKind::ContextModuleFactoryAfterResolve, @@ -1207,24 +1210,24 @@ impl NormalModuleFactoryCreateModule for NormalModuleFactoryCreateModuleTap { #[async_trait] impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap { - async fn run(&self, data: &mut ModuleFactoryCreateData) -> rspack_error::Result> { - let dependency = data - .dependency - .as_context_dependency_mut() - .expect("should be context dependency"); - match self - .function - .call_with_promise(JsBeforeResolveArgs { - request: dependency.request().to_string(), - context: data.context.to_string(), - }) - .await - { - Ok((ret, resolve_data)) => { - dependency.set_request(resolve_data.request); - data.context = resolve_data.context.into(); - Ok(ret) + async fn run(&self, result: BeforeResolveResult) -> rspack_error::Result { + let js_result = match result { + BeforeResolveResult::Ignored => JsContextModuleFactoryBeforeResolveResult::A(false), + BeforeResolveResult::Data(d) => { + JsContextModuleFactoryBeforeResolveResult::B(JsContextModuleFactoryBeforeResolveData { + context: d.context, + request: d.request, + }) } + }; + match self.function.call_with_promise(js_result).await { + Ok(js_result) => match js_result { + napi::bindgen_prelude::Either::A(_) => Ok(BeforeResolveResult::Ignored), + napi::bindgen_prelude::Either::B(d) => Ok(BeforeResolveResult::Data(BeforeResolveData { + context: d.context, + request: d.request, + })), + }, Err(err) => Err(err), } } @@ -1236,29 +1239,29 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap #[async_trait] impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap { - async fn run( - &self, - mut result: AfterResolveResult, - ) -> rspack_error::Result> { - let js_result = self - .function - .call_with_promise(JsContextModuleFactoryAfterResolveResult { - 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?; - match js_result { - Some(js_result) => { - result.resource = js_result.resource; - result.reg_exp = match js_result.reg_exp { + async fn run(&self, result: AfterResolveResult) -> rspack_error::Result { + let js_result = match result { + AfterResolveResult::Ignored => JsContextModuleFactoryAfterResolveResult::A(false), + AfterResolveResult::Data(d) => { + JsContextModuleFactoryAfterResolveResult::B(JsContextModuleFactoryAfterResolveData { + resource: d.resource.to_owned(), + context: d.context.to_owned(), + request: d.request.to_owned(), + reg_exp: d.reg_exp.clone().map(|r| r.to_string()), + }) + } + }; + match self.function.call_with_promise(js_result).await? { + napi::Either::A(_) => Ok(AfterResolveResult::Ignored), + napi::Either::B(d) => Ok(AfterResolveResult::Data(AfterResolveData { + resource: d.resource, + context: d.context, + request: d.request, + reg_exp: match d.reg_exp { Some(r) => Some(RspackRegex::new(&r)?), None => None, - }; - Ok(Some(result)) - } - None => Ok(None), + }, + })), } } diff --git a/crates/rspack_binding_values/src/context_module_factory.rs b/crates/rspack_binding_values/src/context_module_factory.rs index 5dd74d5a2a3..d061d21046f 100644 --- a/crates/rspack_binding_values/src/context_module_factory.rs +++ b/crates/rspack_binding_values/src/context_module_factory.rs @@ -1,9 +1,22 @@ +use napi::bindgen_prelude::Either; use napi_derive::napi; #[napi(object)] -pub struct JsContextModuleFactoryAfterResolveResult { +pub struct JsContextModuleFactoryBeforeResolveData { + pub context: String, + pub request: Option, +} + +pub type JsContextModuleFactoryBeforeResolveResult = + Either; + +#[napi(object)] +pub struct JsContextModuleFactoryAfterResolveData { pub resource: String, pub context: String, pub request: String, pub reg_exp: Option, } + +pub type JsContextModuleFactoryAfterResolveResult = + Either; diff --git a/crates/rspack_core/src/context_module_factory.rs b/crates/rspack_core/src/context_module_factory.rs index 0b2e8fe61e3..5caed04688a 100644 --- a/crates/rspack_core/src/context_module_factory.rs +++ b/crates/rspack_core/src/context_module_factory.rs @@ -13,7 +13,35 @@ use crate::{ }; #[derive(Clone)] -pub struct AfterResolveResult { +pub enum BeforeResolveResult { + Ignored, + Data(BeforeResolveData), +} + +#[derive(Clone)] +pub struct BeforeResolveData { + // context_info + // resolve_options + pub context: String, + pub request: Option, + // assertions + // dependencies + // dependency_type + // file_dependencies + // missing_dependencies + // context_dependencies + // create_data + // cacheable +} + +#[derive(Clone)] +pub enum AfterResolveResult { + Ignored, + Data(AfterResolveData), +} + +#[derive(Clone)] +pub struct AfterResolveData { pub resource: String, pub context: String, // dependencies @@ -37,8 +65,8 @@ pub struct AfterResolveResult { // referenced_exports } -define_hook!(ContextModuleFactoryBeforeResolve: AsyncSeriesBail(data: &mut ModuleFactoryCreateData) -> bool); -define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesWaterfall(data: AfterResolveResult) -> Option); +define_hook!(ContextModuleFactoryBeforeResolve: AsyncSeriesWaterfall(data: BeforeResolveResult) -> BeforeResolveResult); +define_hook!(ContextModuleFactoryAfterResolve: AsyncSeriesWaterfall(data: AfterResolveResult) -> AfterResolveResult); #[derive(Debug, Default)] pub struct ContextModuleFactoryHooks { @@ -90,19 +118,24 @@ impl ContextModuleFactory { &self, data: &mut ModuleFactoryCreateData, ) -> Result> { - if let Some(false) = self + let before_resolve_data = BeforeResolveData { + context: data.context.to_string(), + request: data.request().map(|r| r.to_string()), + }; + + match self .plugin_driver .context_module_factory_hooks .before_resolve - .call(data) + .call(BeforeResolveResult::Data(before_resolve_data)) .await? { - // ignored - // See https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/ContextModuleFactory.js#L115 - return Ok(Some(ModuleFactoryResult::default())); + BeforeResolveResult::Ignored => Ok(Some(ModuleFactoryResult::default())), + BeforeResolveResult::Data(d) => { + data.context = d.context.into(); + Ok(None) + } } - - Ok(None) } fn get_loader_resolver(&self) -> Arc { @@ -255,7 +288,7 @@ impl ContextModuleFactory { context_module_options: &mut ContextModuleOptions, ) -> Result> { let context_options = &context_module_options.context_options; - let after_resolve_result = AfterResolveResult { + let after_resolve_data = AfterResolveData { resource: context_module_options.resource.to_owned(), context: context_options.context.to_owned(), request: context_options.request.to_owned(), @@ -266,12 +299,13 @@ impl ContextModuleFactory { .plugin_driver .context_module_factory_hooks .after_resolve - .call(after_resolve_result) + .call(AfterResolveResult::Data(after_resolve_data)) .await? { - Some(after_resolve_result) => { - context_module_options.resource = after_resolve_result.resource; - context_module_options.context_options.reg_exp = after_resolve_result.reg_exp; + AfterResolveResult::Ignored => Ok(Some(ModuleFactoryResult::default())), + AfterResolveResult::Data(d) => { + context_module_options.resource = d.resource; + context_module_options.context_options.reg_exp = d.reg_exp; let module = ContextModule::new( context_module_options.clone(), @@ -279,7 +313,6 @@ impl ContextModuleFactory { ); Ok(Some(ModuleFactoryResult::new_with_module(Box::new(module)))) } - None => Ok(None), } } } diff --git a/crates/rspack_macros/src/hook.rs b/crates/rspack_macros/src/hook.rs index 7a8295c0169..60ad7831fc2 100644 --- a/crates/rspack_macros/src/hook.rs +++ b/crates/rspack_macros/src/hook.rs @@ -243,11 +243,9 @@ impl ExecKind { #additional_taps let mut data = #args; for tap in all_taps { - if let Some(res) = tap.run(data.clone()).await? { - data = res; - } + data = tap.run(data).await? } - Ok(Some(data)) + Ok(data) } } Self::AsyncParallel => { diff --git a/crates/rspack_plugin_ignore/src/lib.rs b/crates/rspack_plugin_ignore/src/lib.rs index 32fea1f2209..fde7519b897 100644 --- a/crates/rspack_plugin_ignore/src/lib.rs +++ b/crates/rspack_plugin_ignore/src/lib.rs @@ -3,8 +3,8 @@ use std::fmt::Debug; use derivative::Derivative; use futures::future::BoxFuture; use rspack_core::{ - ApplyContext, CompilerOptions, ContextModuleFactoryBeforeResolve, ModuleFactoryCreateData, - NormalModuleFactoryBeforeResolve, Plugin, PluginContext, + ApplyContext, BeforeResolveResult, CompilerOptions, ContextModuleFactoryBeforeResolve, + ModuleFactoryCreateData, NormalModuleFactoryBeforeResolve, Plugin, PluginContext, }; use rspack_error::Result; use rspack_hook::{plugin, plugin_hook}; @@ -37,12 +37,12 @@ impl IgnorePlugin { Self::new_inner(options) } - async fn check_ignore(&self, data: &mut ModuleFactoryCreateData) -> Option { + async fn check_ignore(&self, request: Option<&str>, context: &str) -> Option { if let Some(check_resource) = &self.options.check_resource { - if let Some(request) = data.request() { + if let Some(request) = request { match check_resource { CheckResourceContent::Fn(check) => { - if check(request, data.context.as_ref()) + if check(request, context.as_ref()) .await .expect("run IgnorePlugin check resource error") { @@ -54,9 +54,9 @@ impl IgnorePlugin { } if let Some(resource_reg_exp) = &self.options.resource_reg_exp { - if resource_reg_exp.test(data.request()?) { + if resource_reg_exp.test(request?) { if let Some(context_reg_exp) = &self.options.context_reg_exp { - if context_reg_exp.test(&data.context) { + if context_reg_exp.test(context) { return Some(false); } } else { @@ -71,12 +71,21 @@ impl IgnorePlugin { #[plugin_hook(NormalModuleFactoryBeforeResolve for IgnorePlugin)] async fn nmf_before_resolve(&self, data: &mut ModuleFactoryCreateData) -> Result> { - Ok(self.check_ignore(data).await) + Ok(self.check_ignore(data.request(), &data.context).await) } #[plugin_hook(ContextModuleFactoryBeforeResolve for IgnorePlugin)] -async fn cmf_before_resolve(&self, data: &mut ModuleFactoryCreateData) -> Result> { - Ok(self.check_ignore(data).await) +async fn cmf_before_resolve(&self, data: BeforeResolveResult) -> Result { + match data { + BeforeResolveResult::Ignored => Ok(BeforeResolveResult::Ignored), + BeforeResolveResult::Data(d) => { + if let Some(false) = self.check_ignore(d.request.as_deref(), &d.context).await { + Ok(BeforeResolveResult::Ignored) + } else { + Ok(BeforeResolveResult::Data(d)) + } + } + } } impl Plugin for IgnorePlugin { From 2b84673511e06c01bd7ec7057742c9b9abc78e5e Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 20:21:06 +0800 Subject: [PATCH 05/12] fix: js side logic --- crates/node_binding/binding.d.ts | 11 +++-- .../node_binding/src/plugins/interceptor.rs | 4 +- packages/rspack/src/Compiler.ts | 42 ++++++++----------- packages/rspack/src/ContextModuleFactory.ts | 6 +-- packages/rspack/src/Module.ts | 8 +++- 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 724fb7b46e3..6a14504a3d7 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -291,13 +291,18 @@ export interface JsCompatSource { map?: Buffer } -export interface JsContextModuleFactoryAfterResolveResult { +export interface JsContextModuleFactoryAfterResolveData { resource: string context: string request: string regExp?: string } +export interface JsContextModuleFactoryBeforeResolveData { + context: string + request?: string +} + export interface JsCreateData { request: string userRequest: string @@ -1389,8 +1394,8 @@ export interface RegisterJsTaps { registerNormalModuleFactoryResolveForSchemeTaps: (stages: Array) => Array<{ function: ((arg: JsResolveForSchemeArgs) => Promise<[boolean | undefined, JsResolveForSchemeArgs]>); stage: number; }> registerNormalModuleFactoryAfterResolveTaps: (stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise<[boolean | undefined, JsCreateData | undefined]>); stage: number; }> registerNormalModuleFactoryCreateModuleTaps: (stages: Array) => Array<{ function: ((arg: JsNormalModuleFactoryCreateModuleArgs) => Promise); stage: number; }> - registerContextModuleFactoryBeforeResolveTaps: (stages: Array) => Array<{ function: ((arg: JsBeforeResolveArgs) => Promise<[boolean | undefined, JsBeforeResolveArgs]>); stage: number; }> - registerContextModuleFactoryAfterResolveTaps: (stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise); stage: number; }> + registerContextModuleFactoryBeforeResolveTaps: (stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryBeforeResolveData) => Promise); stage: number; }> + registerContextModuleFactoryAfterResolveTaps: (stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryAfterResolveData) => Promise); stage: number; }> } /** Builtin loader runner */ diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index b653cb69523..31e2bae5cff 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -438,14 +438,14 @@ pub struct RegisterJsTaps { pub register_normal_module_factory_create_module_taps: RegisterFunction>, #[napi( - ts_type = "(stages: Array) => Array<{ function: ((arg: JsContextModuleFactoryBeforeResolveResult) => Promise); stage: number; }>" + ts_type = "(stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryBeforeResolveData) => Promise); stage: number; }>" )] pub register_context_module_factory_before_resolve_taps: RegisterFunction< JsContextModuleFactoryBeforeResolveResult, Promise, >, #[napi( - ts_type = "(stages: Array) => Array<{ function: ((arg: JsContextModuleFactoryAfterResolveResult) => Promise); stage: number; }>" + ts_type = "(stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryAfterResolveData) => Promise); stage: number; }>" )] pub register_context_module_factory_after_resolve_taps: RegisterFunction< JsContextModuleFactoryAfterResolveResult, diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index 9ee4ccc2084..86dcbcbe56d 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -47,7 +47,7 @@ import { assertNotNill } from "./util/assertNotNil"; import { FileSystemInfoEntry } from "./FileSystemInfo"; import { RuntimeGlobals } from "./RuntimeGlobals"; import { tryRunOrWebpackError } from "./lib/HookWebpackError"; -import { CodeGenerationResult, ContextModuleFactoryAfterResolveResult, Module, ResolveData } from "./Module"; +import { CodeGenerationResult, ContextModuleFactoryBeforeResolveResult, ContextModuleFactoryAfterResolveResult, Module, ResolveData } from "./Module"; import { canInherentFromParent } from "./builtin-plugin/base"; import ExecuteModulePlugin from "./ExecuteModulePlugin"; import { Chunk } from "./Chunk"; @@ -530,38 +530,30 @@ class Compiler { binding.RegisterJsTapKind.ContextModuleFactoryBeforeResolve, () => this.compilationParams!.contextModuleFactory.hooks.beforeResolve, - queried => async (arg: binding.JsBeforeResolveArgs) => { - const data: ResolveData = { - request: arg.request, - context: arg.context, - fileDependencies: [], - missingDependencies: [], - contextDependencies: [] - }; - const ret = await queried.promise(data); - return [ret, data]; + queried => async (bindingData: false | binding.JsContextModuleFactoryBeforeResolveData) => { + return queried.promise(bindingData); } ), registerContextModuleFactoryAfterResolveTaps: this.#createHookRegisterTaps( binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve, () => this.compilationParams!.contextModuleFactory.hooks.afterResolve, - queried => async (args: binding.JsContextModuleFactoryAfterResolveResult) => { - const resolveData: ContextModuleFactoryAfterResolveResult = { - resource: args.resource, - regExp: args.regExp ? new RegExp(args.regExp) : undefined, - request: args.request, - context: args.context, - }; - const raw = await queried.promise(resolveData); - const result = raw ? { - resource: raw.resource, - context: '', - request: '', - regExp: raw.regExp?.toString(), + queried => async (bindingData: false | binding.JsContextModuleFactoryAfterResolveData) => { + const data = bindingData ? { + resource: bindingData.resource, + regExp: bindingData.regExp ? new RegExp(bindingData.regExp) : undefined, + request: bindingData.request, + context: bindingData.context, // TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin. dependencies: [], - } : undefined; + } satisfies ContextModuleFactoryAfterResolveResult : false; + const ret = await queried.promise(data); + const result = ret ? { + resource: ret.resource, + context: ret.context, + request: ret.request, + regExp: ret.regExp?.toString(), + } satisfies binding.JsContextModuleFactoryAfterResolveData : undefined; return result; } ) diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index 1075b64baa0..9ba7ec822d4 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -1,5 +1,5 @@ import * as liteTapable from "./lite-tapable"; -import { ContextModuleFactoryAfterResolveResult, ResolveData } from "./Module"; +import { ContextModuleFactoryAfterResolveResult, ContextModuleFactoryBeforeResolveResult } from "./Module"; export class ContextModuleFactory { hooks: { @@ -7,8 +7,8 @@ export class ContextModuleFactory { // resolveForScheme: HookMap< // AsyncSeriesBailHook<[ResourceDataWithData], true | void> // >; - beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ResolveData], false | void>; - afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], false | void | ContextModuleFactoryAfterResolveResult>; + beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryBeforeResolveResult], ContextModuleFactoryBeforeResolveResult | void>; + afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], ContextModuleFactoryAfterResolveResult | void>; }; constructor() { this.hooks = { diff --git a/packages/rspack/src/Module.ts b/packages/rspack/src/Module.ts index 775d28e5629..c9ea04c3e85 100644 --- a/packages/rspack/src/Module.ts +++ b/packages/rspack/src/Module.ts @@ -26,11 +26,17 @@ export type ResolveData = { createData?: CreateData; }; -export type ContextModuleFactoryAfterResolveResult = { +export type ContextModuleFactoryBeforeResolveResult = false | { + context: string; + request?: string; +} + +export type ContextModuleFactoryAfterResolveResult = false | { resource: string; context: string request: string regExp?: RegExp; + dependencies: Array; } export class Module { From 1a6c19267511370015823bad6ab409767d21863c Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 20:22:07 +0800 Subject: [PATCH 06/12] chore: update api.md --- packages/rspack/etc/api.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index ad95b43566a..b3352704c35 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -451,6 +451,17 @@ class AsyncSeriesHook extends Hoo tapPromise(options: Options, fn: Fn): void; } +// @public (undocumented) +class AsyncSeriesWaterfallHook extends Hook { + constructor(args?: ArgumentNames>, name?: string); + // (undocumented) + callAsyncStageRange(queried: QueriedHook, ...args: Append, Callback>): void; + // (undocumented) + tapAsync(options: Options, fn: FnWithCallback): void; + // (undocumented) + tapPromise(options: Options, fn: Fn): void; +} + // @public (undocumented) const AsyncWebAssemblyModulesPlugin: { new (): { @@ -1640,11 +1651,26 @@ class ContextModuleFactory { constructor(); // (undocumented) hooks: { - beforeResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>; - afterResolve: liteTapable.AsyncSeriesBailHook<[ResolveData], false | void>; + beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryBeforeResolveResult], ContextModuleFactoryBeforeResolveResult | void>; + afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], ContextModuleFactoryAfterResolveResult | void>; }; } +// @public (undocumented) +type ContextModuleFactoryAfterResolveResult = false | { + resource: string; + context: string; + request: string; + regExp?: RegExp; + dependencies: Array; +}; + +// @public (undocumented) +type ContextModuleFactoryBeforeResolveResult = false | { + context: string; + request?: string; +}; + // @public (undocumented) export const CopyRspackPlugin: { new (copy: CopyRspackPluginOptions): { @@ -4565,6 +4591,7 @@ declare namespace liteTapable { AsyncParallelHook, AsyncSeriesHook, AsyncSeriesBailHook, + AsyncSeriesWaterfallHook, HookMapKey, HookFactory, HookMapInterceptor, From fb745a21d370f3bec0a700b9cea8f12cbb68fdd2 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 21:12:52 +0800 Subject: [PATCH 07/12] fix: use AsyncSeriesWaterfallHook in js side --- packages/rspack/src/ContextModuleFactory.ts | 4 +-- packages/rspack/src/lite-tapable/index.ts | 36 ++++++++++----------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index 9ba7ec822d4..c4627790744 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -25,8 +25,8 @@ export class ContextModuleFactory { // /** @type {AsyncSeriesBailHook<[ResolveData], Module>} */ // factorize: new AsyncSeriesBailHook(["resolveData"]), // /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */ - beforeResolve: new liteTapable.AsyncSeriesBailHook(["resolveData"]), - afterResolve: new liteTapable.AsyncSeriesBailHook(["resolveData"]) + beforeResolve: new liteTapable.AsyncSeriesWaterfallHook(["resolveData"]), + afterResolve: new liteTapable.AsyncSeriesWaterfallHook(["resolveData"]) // /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], Module | void>} */ // createModule: new AsyncSeriesBailHook(["createData", "resolveData"]), // /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], Module>} */ diff --git a/packages/rspack/src/lite-tapable/index.ts b/packages/rspack/src/lite-tapable/index.ts index a785266a8a6..9e0833b8adf 100644 --- a/packages/rspack/src/lite-tapable/index.ts +++ b/packages/rspack/src/lite-tapable/index.ts @@ -791,30 +791,26 @@ export class AsyncSeriesWaterfallHook< stageRange: [from, to], tapsInRange } = queried; - const args2 = [...args]; - const cb = args2.pop() as Callback; + let data = args[0] as R; + const cb = args[1] as Callback; if (from === minStage) { - this._runCallInterceptors(...args2); + this._runCallInterceptors(data); } const done = () => { this._runDoneInterceptors(); - cb(null); + cb(null, data); }; 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); + const promise = tap.fn(data); if (!promise || !promise.then) { throw new Error( "Tap function (tapPromise) did not return promise (returned " + @@ -826,8 +822,9 @@ export class AsyncSeriesWaterfallHook< (r: R) => { index += 1; if (r !== undefined) { - result(r); - } else if (index === tapsInRange.length) { + data = r + } + if (index === tapsInRange.length) { done(); } else { next(); @@ -839,15 +836,16 @@ export class AsyncSeriesWaterfallHook< } ); } else if (tap.type === "async") { - tap.fn(...args2, (e: Error, r: R) => { + tap.fn(data, (e: Error, r: R) => { if (e) { index = tapsInRange.length; error(e); } else { index += 1; if (r !== undefined) { - result(r); - } else if (index === tapsInRange.length) { + data = r + } + if (index === tapsInRange.length) { done(); } else { next(); @@ -856,9 +854,11 @@ export class AsyncSeriesWaterfallHook< }); } else { let hasError = false; - let r = undefined; try { - r = tap.fn(...args2); + const r = tap.fn(data); + if (r !== undefined) { + data = r + } } catch (e) { hasError = true; index = tapsInRange.length; @@ -866,9 +866,7 @@ export class AsyncSeriesWaterfallHook< } if (!hasError) { index += 1; - if (r !== undefined) { - result(r); - } else if (index === tapsInRange.length) { + if (index === tapsInRange.length) { done(); } else { next(); From 390745f29926802e6ac2287128fe9655026e279c Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 21:24:15 +0800 Subject: [PATCH 08/12] fix: format js --- packages/rspack/src/Compiler.ts | 65 ++++++++++++++------- packages/rspack/src/ContextModuleFactory.ts | 15 ++++- packages/rspack/src/Module.ts | 28 +++++---- packages/rspack/src/lite-tapable/index.ts | 6 +- 4 files changed, 74 insertions(+), 40 deletions(-) diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index 018f258a160..836206793a4 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -47,7 +47,12 @@ import { assertNotNill } from "./util/assertNotNil"; import { FileSystemInfoEntry } from "./FileSystemInfo"; import { RuntimeGlobals } from "./RuntimeGlobals"; import { tryRunOrWebpackError } from "./lib/HookWebpackError"; -import { CodeGenerationResult, ContextModuleFactoryBeforeResolveResult, ContextModuleFactoryAfterResolveResult, Module, ResolveData } from "./Module"; +import { + CodeGenerationResult, + ContextModuleFactoryAfterResolveResult, + Module, + ResolveData +} from "./Module"; import { canInherentFromParent } from "./builtin-plugin/base"; import ExecuteModulePlugin from "./ExecuteModulePlugin"; import { Chunk } from "./Chunk"; @@ -530,32 +535,48 @@ class Compiler { binding.RegisterJsTapKind.ContextModuleFactoryBeforeResolve, () => this.compilationParams!.contextModuleFactory.hooks.beforeResolve, - queried => async (bindingData: false | binding.JsContextModuleFactoryBeforeResolveData) => { - return queried.promise(bindingData); - } + queried => + async ( + bindingData: + | false + | binding.JsContextModuleFactoryBeforeResolveData + ) => { + return queried.promise(bindingData); + } ), registerContextModuleFactoryAfterResolveTaps: this.#createHookRegisterTaps( binding.RegisterJsTapKind.ContextModuleFactoryAfterResolve, () => this.compilationParams!.contextModuleFactory.hooks.afterResolve, - queried => async (bindingData: false | binding.JsContextModuleFactoryAfterResolveData) => { - const data = bindingData ? { - resource: bindingData.resource, - regExp: bindingData.regExp ? new RegExp(bindingData.regExp) : undefined, - request: bindingData.request, - context: bindingData.context, - // TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin. - dependencies: [], - } satisfies ContextModuleFactoryAfterResolveResult : false; - const ret = await queried.promise(data); - const result = ret ? { - resource: ret.resource, - context: ret.context, - request: ret.request, - regExp: ret.regExp?.toString(), - } satisfies binding.JsContextModuleFactoryAfterResolveData : undefined; - return result; - } + queried => + async ( + bindingData: + | false + | binding.JsContextModuleFactoryAfterResolveData + ) => { + const data = bindingData + ? ({ + resource: bindingData.resource, + regExp: bindingData.regExp + ? new RegExp(bindingData.regExp) + : undefined, + request: bindingData.request, + context: bindingData.context, + // TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin. + dependencies: [] + } satisfies ContextModuleFactoryAfterResolveResult) + : false; + const ret = await queried.promise(data); + const result = ret + ? ({ + resource: ret.resource, + context: ret.context, + request: ret.request, + regExp: ret.regExp?.toString() + } satisfies binding.JsContextModuleFactoryAfterResolveData) + : undefined; + return result; + } ) }; diff --git a/packages/rspack/src/ContextModuleFactory.ts b/packages/rspack/src/ContextModuleFactory.ts index c4627790744..fa56abea52a 100644 --- a/packages/rspack/src/ContextModuleFactory.ts +++ b/packages/rspack/src/ContextModuleFactory.ts @@ -1,5 +1,8 @@ import * as liteTapable from "./lite-tapable"; -import { ContextModuleFactoryAfterResolveResult, ContextModuleFactoryBeforeResolveResult } from "./Module"; +import { + ContextModuleFactoryAfterResolveResult, + ContextModuleFactoryBeforeResolveResult +} from "./Module"; export class ContextModuleFactory { hooks: { @@ -7,8 +10,14 @@ export class ContextModuleFactory { // resolveForScheme: HookMap< // AsyncSeriesBailHook<[ResourceDataWithData], true | void> // >; - beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryBeforeResolveResult], ContextModuleFactoryBeforeResolveResult | void>; - afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], ContextModuleFactoryAfterResolveResult | void>; + beforeResolve: liteTapable.AsyncSeriesWaterfallHook< + [ContextModuleFactoryBeforeResolveResult], + ContextModuleFactoryBeforeResolveResult | void + >; + afterResolve: liteTapable.AsyncSeriesWaterfallHook< + [ContextModuleFactoryAfterResolveResult], + ContextModuleFactoryAfterResolveResult | void + >; }; constructor() { this.hooks = { diff --git a/packages/rspack/src/Module.ts b/packages/rspack/src/Module.ts index c9ea04c3e85..303eee73fc8 100644 --- a/packages/rspack/src/Module.ts +++ b/packages/rspack/src/Module.ts @@ -26,18 +26,22 @@ export type ResolveData = { createData?: CreateData; }; -export type ContextModuleFactoryBeforeResolveResult = false | { - context: string; - request?: string; -} - -export type ContextModuleFactoryAfterResolveResult = false | { - resource: string; - context: string - request: string - regExp?: RegExp; - dependencies: Array; -} +export type ContextModuleFactoryBeforeResolveResult = + | false + | { + context: string; + request?: string; + }; + +export type ContextModuleFactoryAfterResolveResult = + | false + | { + resource: string; + context: string; + request: string; + regExp?: RegExp; + dependencies: Array; + }; export class Module { #inner: JsModule; diff --git a/packages/rspack/src/lite-tapable/index.ts b/packages/rspack/src/lite-tapable/index.ts index 9e0833b8adf..8e2905fa027 100644 --- a/packages/rspack/src/lite-tapable/index.ts +++ b/packages/rspack/src/lite-tapable/index.ts @@ -822,7 +822,7 @@ export class AsyncSeriesWaterfallHook< (r: R) => { index += 1; if (r !== undefined) { - data = r + data = r; } if (index === tapsInRange.length) { done(); @@ -843,7 +843,7 @@ export class AsyncSeriesWaterfallHook< } else { index += 1; if (r !== undefined) { - data = r + data = r; } if (index === tapsInRange.length) { done(); @@ -857,7 +857,7 @@ export class AsyncSeriesWaterfallHook< try { const r = tap.fn(data); if (r !== undefined) { - data = r + data = r; } } catch (e) { hasError = true; From 4498c1622e6c2bba3b5b1c8f05151673bed939db Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 9 May 2024 21:33:23 +0800 Subject: [PATCH 09/12] fix: cargo lint --- crates/rspack_plugin_ignore/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rspack_plugin_ignore/src/lib.rs b/crates/rspack_plugin_ignore/src/lib.rs index fde7519b897..4b2fe3461f4 100644 --- a/crates/rspack_plugin_ignore/src/lib.rs +++ b/crates/rspack_plugin_ignore/src/lib.rs @@ -42,7 +42,7 @@ impl IgnorePlugin { if let Some(request) = request { match check_resource { CheckResourceContent::Fn(check) => { - if check(request, context.as_ref()) + if check(request, context) .await .expect("run IgnorePlugin check resource error") { From efa05dbefbfb7fba928a5222c91bd5a39c24c19d Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Fri, 10 May 2024 10:17:45 +0800 Subject: [PATCH 10/12] fix: context module factory afterResolve hook --- packages/rspack/src/Compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index 836206793a4..d64b561a898 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -574,7 +574,7 @@ class Compiler { request: ret.request, regExp: ret.regExp?.toString() } satisfies binding.JsContextModuleFactoryAfterResolveData) - : undefined; + : false; return result; } ) From b19e926bc2aec7ce4ff19cab61588b0e6c848650 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Fri, 10 May 2024 11:08:07 +0800 Subject: [PATCH 11/12] chore: update snapshot --- .../tests/errorCases/warning-test-push.js | 4 ++-- .../tests/errorCases/warning-test-shift.js | 4 ++-- .../tests/errorCases/warning-test-splice-1.js | 4 ++-- .../tests/errorCases/warning-test-splice-2.js | 4 ++-- packages/rspack/etc/api.md | 8 ++++++-- packages/rspack/src/Compiler.ts | 2 +- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/rspack-test-tools/tests/errorCases/warning-test-push.js b/packages/rspack-test-tools/tests/errorCases/warning-test-push.js index 40a8a9e17ae..a13ba23db6a 100644 --- a/packages/rspack-test-tools/tests/errorCases/warning-test-push.js +++ b/packages/rspack-test-tools/tests/errorCases/warning-test-push.js @@ -19,8 +19,8 @@ module.exports = { "errors": Array [], "warnings": Array [ Object { - "formatted": " ⚠ Error: test push\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-push.js:10:33\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", - "message": " ⚠ Error: test push\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-push.js:10:33\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", + "formatted": " ⚠ Error: test push\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-push.js:10:33\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", + "message": " ⚠ Error: test push\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-push.js:10:33\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", }, Object { "formatted": " ⚠ Module parse warning:\\n ╰─▶ ⚠ Module parse failed: require.main.require() is not supported by Rspack.\\n ╭────\\n 1 │ require.main.require('./file');\\n · ──────────────────────────────\\n ╰────\\n \\n", diff --git a/packages/rspack-test-tools/tests/errorCases/warning-test-shift.js b/packages/rspack-test-tools/tests/errorCases/warning-test-shift.js index d7f67da0e25..ed239f1456c 100644 --- a/packages/rspack-test-tools/tests/errorCases/warning-test-shift.js +++ b/packages/rspack-test-tools/tests/errorCases/warning-test-shift.js @@ -23,8 +23,8 @@ module.exports = { "errors": Array [], "warnings": Array [ Object { - "formatted": " ⚠ Error: test unshift\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-shift.js:13:37\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", - "message": " ⚠ Error: test unshift\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-shift.js:13:37\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", + "formatted": " ⚠ Error: test unshift\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-shift.js:13:37\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", + "message": " ⚠ Error: test unshift\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-shift.js:13:37\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", }, ], } diff --git a/packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js b/packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js index 0693d2f2dee..f1b86d30985 100644 --- a/packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js +++ b/packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js @@ -19,8 +19,8 @@ module.exports = { "errors": Array [], "warnings": Array [ Object { - "formatted": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", - "message": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", + "formatted": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", + "message": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-1.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", }, ], } diff --git a/packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js b/packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js index bd8b5f13986..016b2f215cd 100644 --- a/packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js +++ b/packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js @@ -19,8 +19,8 @@ module.exports = { "errors": Array [], "warnings": Array [ Object { - "formatted": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", - "message": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:745:65\\n", + "formatted": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", + "message": " ⚠ Error: test splice\\n │ at packages/rspack-test-tools/tests/errorCases/warning-test-splice-2.js:10:41\\n │ at Hook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), :9:1)\\n │ at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (node_modules/tapable/lib/Hook.js:18:14)\\n │ at packages/rspack/dist/Compiler.js:419:41\\n │ at packages/rspack/dist/Compiler.js:751:65\\n", }, Object { "formatted": " ⚠ Module parse warning:\\n ╰─▶ ⚠ Module parse failed: require.main.require() is not supported by Rspack.\\n ╭────\\n 1 │ require.main.require('./file');\\n · ──────────────────────────────\\n ╰────\\n \\n", diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index 2b322251865..15720c08bdb 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -1474,8 +1474,12 @@ class ContextModuleFactory { constructor(); // (undocumented) hooks: { - beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryBeforeResolveResult], ContextModuleFactoryBeforeResolveResult | void>; - afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ContextModuleFactoryAfterResolveResult], ContextModuleFactoryAfterResolveResult | void>; + beforeResolve: liteTapable.AsyncSeriesWaterfallHook<[ + ContextModuleFactoryBeforeResolveResult + ], ContextModuleFactoryBeforeResolveResult | void>; + afterResolve: liteTapable.AsyncSeriesWaterfallHook<[ + ContextModuleFactoryAfterResolveResult + ], ContextModuleFactoryAfterResolveResult | void>; }; } diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index d64b561a898..bf9084bb6d5 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -515,7 +515,7 @@ class Compiler { createData: arg.createData }; const ret = await queried.promise(data); - return [!!ret, ret]; + return [ret, data.createData]; } ), registerNormalModuleFactoryCreateModuleTaps: this.#createHookRegisterTaps( From 9ea9ff3521e0fb2e1a510116193485a951f9e372 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Fri, 10 May 2024 13:25:43 +0800 Subject: [PATCH 12/12] feat: new test case for context module factory before resolve hook --- .../node_binding/src/plugins/interceptor.rs | 32 +++++++++++-------- .../rspack_core/src/context_module_factory.rs | 8 ++--- .../context-module-before-resolve/index.js | 15 +++++++++ .../locale/en.js | 1 + .../locale/fr.js | 1 + .../locale/zh.js | 1 + .../webpack.config.js | 26 +++++++++++++++ 7 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/index.js create mode 100644 packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/en.js create mode 100644 packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/fr.js create mode 100644 packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/zh.js create mode 100644 packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/webpack.config.js diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index 686c33c4cb6..0937ea7df60 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -1219,10 +1219,13 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap match self.function.call_with_promise(js_result).await { Ok(js_result) => match js_result { napi::bindgen_prelude::Either::A(_) => Ok(BeforeResolveResult::Ignored), - napi::bindgen_prelude::Either::B(d) => Ok(BeforeResolveResult::Data(BeforeResolveData { - context: d.context, - request: d.request, - })), + napi::bindgen_prelude::Either::B(d) => { + let data = BeforeResolveData { + context: d.context, + request: d.request, + }; + Ok(BeforeResolveResult::Data(Box::new(data))) + } }, Err(err) => Err(err), } @@ -1249,15 +1252,18 @@ impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap { }; match self.function.call_with_promise(js_result).await? { napi::Either::A(_) => Ok(AfterResolveResult::Ignored), - napi::Either::B(d) => Ok(AfterResolveResult::Data(AfterResolveData { - resource: d.resource, - context: d.context, - request: d.request, - reg_exp: match d.reg_exp { - Some(r) => Some(RspackRegex::new(&r)?), - None => None, - }, - })), + napi::Either::B(d) => { + let data = AfterResolveData { + resource: d.resource, + context: d.context, + request: d.request, + reg_exp: match d.reg_exp { + Some(r) => Some(RspackRegex::new(&r)?), + None => None, + }, + }; + Ok(AfterResolveResult::Data(Box::new(data))) + } } } diff --git a/crates/rspack_core/src/context_module_factory.rs b/crates/rspack_core/src/context_module_factory.rs index 5caed04688a..6a41cd8bd26 100644 --- a/crates/rspack_core/src/context_module_factory.rs +++ b/crates/rspack_core/src/context_module_factory.rs @@ -15,7 +15,7 @@ use crate::{ #[derive(Clone)] pub enum BeforeResolveResult { Ignored, - Data(BeforeResolveData), + Data(Box), } #[derive(Clone)] @@ -37,7 +37,7 @@ pub struct BeforeResolveData { #[derive(Clone)] pub enum AfterResolveResult { Ignored, - Data(AfterResolveData), + Data(Box), } #[derive(Clone)] @@ -127,7 +127,7 @@ impl ContextModuleFactory { .plugin_driver .context_module_factory_hooks .before_resolve - .call(BeforeResolveResult::Data(before_resolve_data)) + .call(BeforeResolveResult::Data(Box::new(before_resolve_data))) .await? { BeforeResolveResult::Ignored => Ok(Some(ModuleFactoryResult::default())), @@ -299,7 +299,7 @@ impl ContextModuleFactory { .plugin_driver .context_module_factory_hooks .after_resolve - .call(AfterResolveResult::Data(after_resolve_data)) + .call(AfterResolveResult::Data(Box::new(after_resolve_data))) .await? { AfterResolveResult::Ignored => Ok(Some(ModuleFactoryResult::default())), diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/index.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/index.js new file mode 100644 index 00000000000..e75f436b87e --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/index.js @@ -0,0 +1,15 @@ +it("should compile", async () => { + try { + ["fr.js"].map(file => { + require("./locale/" + file); + }); + } catch (e) { + expect(e.message).toContain("Cannot find module './fr.js'") + } + ["zh.js"].map(file => { + expect(require("./locale/" + file).default).toBe("你好"); + }); + ["en.js"].map(file => { + expect(require("./locale/" + file).default).toBe("hello"); + }); +}); diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/en.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/en.js new file mode 100644 index 00000000000..b514bd48f97 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/en.js @@ -0,0 +1 @@ +export default 'hello'; diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/fr.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/fr.js new file mode 100644 index 00000000000..a2bbb2f7390 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/fr.js @@ -0,0 +1 @@ +export default 'bonjour'; diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/zh.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/zh.js new file mode 100644 index 00000000000..9d379cf2367 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/locale/zh.js @@ -0,0 +1 @@ +export default '你好'; \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/webpack.config.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/webpack.config.js new file mode 100644 index 00000000000..fcc5a341e33 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/webpack.config.js @@ -0,0 +1,26 @@ +const pluginName = "plugin"; + +class Plugin { + apply(compiler) { + compiler.hooks.contextModuleFactory.tap( + pluginName, + contextModuleFactory => { + contextModuleFactory.hooks.beforeResolve.tap(pluginName, resolveData => { + if (resolveData.request.includes("./locale")) { + resolveData.regExp = /[/\\](en(\.js)?|zh(\.js)?)$/; + return resolveData; + } + }); + } + ); + } +} +/**@type {import('@rspack/cli').Configuration}*/ +module.exports = { + context: __dirname, + entry: "./index.js", + module: { + rules: [] + }, + plugins: [new Plugin()] +};