From 27188f20a4d831201961a3808690c9c350489e02 Mon Sep 17 00:00:00 2001 From: Cong-Cong Pan Date: Thu, 10 Oct 2024 17:53:45 +0800 Subject: [PATCH] feat: support dependencies in resolve hook callback (#7949) * feat: dependencies in context module factory hook * feat: ContextModuleFactoryBeforeResolveData * feat: update test case * fix: cargo lint * chore: update api docs * feat: JsDependency and JsDependencyMut * fix: remove lifecycle * chore: update api * fix: Dependency --- crates/node_binding/binding.d.ts | 33 ++- .../src/compilation/entries.rs | 45 ++-- .../src/context_module_factory.rs | 12 +- .../rspack_binding_values/src/dependency.rs | 111 ++++++--- crates/rspack_binding_values/src/lib.rs | 2 +- crates/rspack_binding_values/src/module.rs | 11 +- .../rspack.config.js | 4 + packages/rspack/etc/api.md | 116 +++++----- packages/rspack/src/Compiler.ts | 18 +- packages/rspack/src/DependenciesBlock.ts | 2 +- packages/rspack/src/Dependency.ts | 53 +++-- packages/rspack/src/Module.ts | 213 +++++++++++++----- 12 files changed, 415 insertions(+), 205 deletions(-) diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 89e1d305c14..b40897b1e85 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -20,7 +20,7 @@ export class ExternalObject { } } export class DependenciesBlockDto { - get dependencies(): Array + get dependencies(): Array get blocks(): Array } export type DependenciesBlockDTO = DependenciesBlockDto @@ -41,16 +41,9 @@ export class DependenciesDto { } export type DependenciesDTO = DependenciesDto -export class DependencyDto { - get type(): string - get category(): string - get request(): string | undefined -} -export type DependencyDTO = DependencyDto - export class EntryDataDto { - get dependencies(): Array - get includeDependencies(): Array + get dependencies(): Array + get includeDependencies(): Array get options(): EntryOptionsDto } export type EntryDataDTO = EntryDataDto @@ -132,6 +125,7 @@ export class JsContextModuleFactoryAfterResolveData { set regExp(rawRegExp: RawRegex | undefined) get recursive(): boolean set recursive(recursive: boolean) + get dependencies(): Array } export class JsContextModuleFactoryBeforeResolveData { @@ -145,6 +139,21 @@ export class JsContextModuleFactoryBeforeResolveData { set recursive(recursive: boolean) } +export class JsDependency { + get type(): string + get category(): string + get request(): string | undefined + get critical(): boolean +} + +export class JsDependencyMut { + get type(): string + get category(): string + get request(): string | undefined + get critical(): boolean + set critical(val: boolean) +} + export class JsEntries { clear(): void get size(): number @@ -526,8 +535,8 @@ export interface JsDiagnosticLocation { } export interface JsEntryData { - dependencies: Array - includeDependencies: Array + dependencies: Array + includeDependencies: Array options: JsEntryOptions } diff --git a/crates/rspack_binding_values/src/compilation/entries.rs b/crates/rspack_binding_values/src/compilation/entries.rs index 3ae57f39501..03be0ca4ca4 100644 --- a/crates/rspack_binding_values/src/compilation/entries.rs +++ b/crates/rspack_binding_values/src/compilation/entries.rs @@ -2,7 +2,7 @@ use napi_derive::napi; use rspack_core::{ChunkLoading, Compilation, EntryData, EntryOptions, EntryRuntime}; use rspack_napi::napi::bindgen_prelude::*; -use crate::{dependency::DependencyDTO, entry::JsEntryOptions, library::JsLibraryOptions}; +use crate::{dependency::JsDependency, entry::JsEntryOptions, library::JsLibraryOptions}; #[napi] pub struct EntryOptionsDTO(EntryOptions); @@ -152,8 +152,8 @@ impl EntryOptionsDTO { #[napi(object, object_to_js = false)] pub struct JsEntryData { - pub dependencies: Vec>, - pub include_dependencies: Vec>, + pub dependencies: Vec>, + pub include_dependencies: Vec>, pub options: JsEntryOptions, } @@ -163,12 +163,12 @@ impl From for EntryData { dependencies: value .dependencies .into_iter() - .map(|dep| dep.dependency_id) + .map(|dep| *dep.id()) .collect::>(), include_dependencies: value .include_dependencies .into_iter() - .map(|dep| dep.dependency_id) + .map(|dep| *dep.id()) .collect::>(), options: value.options.into(), } @@ -184,36 +184,33 @@ pub struct EntryDataDTO { #[napi] impl EntryDataDTO { #[napi(getter)] - pub fn dependencies(&'static self, env: Env) -> Result>> { + pub fn dependencies(&'static self) -> Vec { + let module_graph = self.compilation.get_module_graph(); self .entry_data .dependencies - .clone() - .into_iter() - .map(|id| { - let js_dep = DependencyDTO::new(id, self.compilation); - let instance = js_dep.into_instance(env)?; - Ok(instance) + .iter() + .map(|dependency_id| { + #[allow(clippy::unwrap_used)] + let dep = module_graph.dependency_by_id(dependency_id).unwrap(); + JsDependency::new(dep) }) - .collect::>>>() + .collect::>() } #[napi(getter)] - pub fn include_dependencies( - &'static self, - env: Env, - ) -> Result>> { + pub fn include_dependencies(&'static self) -> Vec { + let module_graph = self.compilation.get_module_graph(); self .entry_data .include_dependencies - .clone() - .into_iter() - .map(|id| { - let js_dep = DependencyDTO::new(id, self.compilation); - let instance = js_dep.into_instance(env)?; - Ok(instance) + .iter() + .map(|dependency_id| { + #[allow(clippy::unwrap_used)] + let dep = module_graph.dependency_by_id(dependency_id).unwrap(); + JsDependency::new(dep) }) - .collect::>>>() + .collect::>() } #[napi(getter)] diff --git a/crates/rspack_binding_values/src/context_module_factory.rs b/crates/rspack_binding_values/src/context_module_factory.rs index a8e52868970..3dbff18b36c 100644 --- a/crates/rspack_binding_values/src/context_module_factory.rs +++ b/crates/rspack_binding_values/src/context_module_factory.rs @@ -4,7 +4,7 @@ use napi::bindgen_prelude::{ use napi_derive::napi; use rspack_core::{AfterResolveData, BeforeResolveData}; -use crate::RawRegex; +use crate::{JsDependencyMut, RawRegex}; #[napi] pub struct JsContextModuleFactoryBeforeResolveData(Box); @@ -173,6 +173,16 @@ impl JsContextModuleFactoryAfterResolveData { pub fn set_recursive(&mut self, recursive: bool) { self.0.recursive = recursive; } + + #[napi(getter)] + pub fn dependencies(&mut self) -> Vec { + self + .0 + .dependencies + .iter_mut() + .map(JsDependencyMut::new) + .collect::>() + } } pub struct JsContextModuleFactoryAfterResolveDataWrapper(Box); diff --git a/crates/rspack_binding_values/src/dependency.rs b/crates/rspack_binding_values/src/dependency.rs index 6427449f2af..1d85b7e7218 100644 --- a/crates/rspack_binding_values/src/dependency.rs +++ b/crates/rspack_binding_values/src/dependency.rs @@ -1,57 +1,108 @@ use napi_derive::napi; -use rspack_core::{Compilation, Dependency, DependencyId, ModuleDependency, ModuleGraph}; +use rspack_core::{BoxDependency, DependencyId}; +// JsDependency allows JS-side access to a Dependency instance that has already +// been processed and stored in the Compilation. #[napi] -pub struct DependencyDTO { - pub(crate) dependency_id: DependencyId, - pub(crate) compilation: &'static Compilation, +pub struct JsDependency(&'static BoxDependency); + +impl JsDependency { + pub(crate) fn new(dependency: &BoxDependency) -> Self { + // SAFETY: + // The lifetime of the &mut BoxDependency reference is extended to 'static. + // Accessing fields and methods on the Rust object from the JS side after the Rust object's + // lifetime has ended is undefined behavior, which we currently disregard. + let dependency = + unsafe { std::mem::transmute::<&BoxDependency, &'static BoxDependency>(dependency) }; + Self(dependency) + } + + pub(crate) fn id(&self) -> &DependencyId { + self.0.id() + } } -impl DependencyDTO { - pub(crate) fn new(dependency_id: DependencyId, compilation: &'static Compilation) -> Self { - Self { - dependency_id, - compilation, +#[napi] +impl JsDependency { + #[napi(getter)] + pub fn get_type(&self) -> &str { + self.0.dependency_type().as_str() + } + + #[napi(getter)] + pub fn category(&self) -> &str { + self.0.category().as_str() + } + + #[napi(getter)] + pub fn request(&self) -> napi::Either<&str, ()> { + match self.0.as_module_dependency() { + Some(dep) => napi::Either::A(dep.request()), + None => napi::Either::B(()), } } - fn dependency<'a>(&self, module_graph: &'a ModuleGraph) -> &'a dyn Dependency { - module_graph - .dependency_by_id(&self.dependency_id) - .unwrap_or_else(|| panic!("Failed to get dependency by id = {:?}", &self.dependency_id)) - .as_ref() + #[napi(getter)] + pub fn critical(&self) -> bool { + match self.0.as_context_dependency() { + Some(dep) => dep.critical().is_some(), + None => false, + } } +} - fn module_dependency<'a>( - &self, - module_graph: &'a ModuleGraph, - ) -> Option<&'a dyn ModuleDependency> { - self.dependency(module_graph).as_module_dependency() +// JsDependency represents a Dependency instance that is currently being processed. +// It is in the make stage and has not yet been added to the Compilation. +#[napi] +pub struct JsDependencyMut(&'static mut BoxDependency); + +impl JsDependencyMut { + pub(crate) fn new(dependency: &mut BoxDependency) -> Self { + // SAFETY: + // The lifetime of the &mut BoxDependency reference is extended to 'static. + // Accessing fields and methods on the Rust object from the JS side after the Rust object's + // lifetime has ended is undefined behavior, which we currently disregard. + let dependency = + unsafe { std::mem::transmute::<&mut BoxDependency, &'static mut BoxDependency>(dependency) }; + Self(dependency) } } #[napi] -impl DependencyDTO { +impl JsDependencyMut { #[napi(getter)] pub fn get_type(&self) -> &str { - let module_graph = self.compilation.get_module_graph(); - let dep = self.dependency(&module_graph); - dep.dependency_type().as_str() + self.0.dependency_type().as_str() } #[napi(getter)] pub fn category(&self) -> &str { - let module_graph = self.compilation.get_module_graph(); - let dep = self.dependency(&module_graph); - dep.category().as_str() + self.0.category().as_str() } #[napi(getter)] - pub fn request(&self) -> napi::Either { - let module_graph = self.compilation.get_module_graph(); - match self.module_dependency(&module_graph) { - Some(dep) => napi::Either::A(dep.request().to_string()), + pub fn request(&self) -> napi::Either<&str, ()> { + match self.0.as_module_dependency() { + Some(dep) => napi::Either::A(dep.request()), None => napi::Either::B(()), } } + + #[napi(getter)] + pub fn critical(&self) -> bool { + match self.0.as_context_dependency() { + Some(dep) => dep.critical().is_some(), + None => false, + } + } + + #[napi(setter)] + pub fn set_critical(&mut self, val: bool) { + if let Some(dep) = self.0.as_context_dependency_mut() { + let critical = dep.critical_mut(); + if !val { + *critical = None; + } + } + } } diff --git a/crates/rspack_binding_values/src/lib.rs b/crates/rspack_binding_values/src/lib.rs index ba4a9518373..deeeea82032 100644 --- a/crates/rspack_binding_values/src/lib.rs +++ b/crates/rspack_binding_values/src/lib.rs @@ -32,7 +32,7 @@ pub use chunk_group::*; pub use codegen_result::*; pub use compilation::*; pub use context_module_factory::*; -pub use dependency::DependencyDTO; +pub use dependency::*; pub use filename::*; pub use html::*; pub use module::*; diff --git a/crates/rspack_binding_values/src/module.rs b/crates/rspack_binding_values/src/module.rs index 8bd4d25c2f8..f6ca33fb29f 100644 --- a/crates/rspack_binding_values/src/module.rs +++ b/crates/rspack_binding_values/src/module.rs @@ -14,7 +14,7 @@ use rustc_hash::FxHashMap as HashMap; use sys::napi_env; use super::{JsCompatSource, ToJsCompatSource}; -use crate::{DependencyDTO, JsChunk, JsCodegenerationResults}; +use crate::{JsChunk, JsCodegenerationResults, JsDependency}; #[derive(Default)] #[napi(object)] @@ -52,14 +52,17 @@ impl DependenciesBlockDTO { #[napi] impl DependenciesBlockDTO { #[napi(getter)] - pub fn dependencies(&self) -> Vec { + pub fn dependencies(&self) -> Vec { let module_graph = self.compilation.get_module_graph(); let block = self.block(&module_graph); block .get_dependencies() .iter() - .cloned() - .map(|dep_id| DependencyDTO::new(dep_id, self.compilation)) + .map(|dependency_id| { + #[allow(clippy::unwrap_used)] + let dep = module_graph.dependency_by_id(dependency_id).unwrap(); + JsDependency::new(dep) + }) .collect::>() } diff --git a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/rspack.config.js b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/rspack.config.js index dfb8bfdac3f..52848a17dd5 100644 --- a/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/rspack.config.js +++ b/packages/rspack-test-tools/tests/configCases/hooks/context-module-before-resolve/rspack.config.js @@ -10,11 +10,15 @@ class Plugin { resolveData.regExp = /[/\\](en(\.js)?|zh(\.js)?)$/; return resolveData; } + for (const d of resolveData.dependencies) { + if (d.critical) d.critical = false; + } }); } ); } } + /**@type {import("@rspack/core").Configuration}*/ module.exports = { context: __dirname, diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index fe59b0b96ca..8ee6d900b17 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -18,7 +18,6 @@ import { cleanupGlobalTrace } from '@rspack/binding'; import { Compiler as Compiler_2 } from '../Compiler'; import { default as default_2 } from './util/hash'; import type { DependenciesBlockDTO } from '@rspack/binding'; -import type { DependencyDTO } from '@rspack/binding'; import { RawEvalDevToolModulePluginOptions as EvalDevToolModulePluginOptions } from '@rspack/binding'; import { EventEmitter } from 'events'; import { ExternalObject } from '@rspack/binding'; @@ -41,7 +40,10 @@ import { JsChunkPathData } from '@rspack/binding'; import type { JsCodegenerationResult } from '@rspack/binding'; import { JsCompilation } from '@rspack/binding'; import type { JsContextModuleFactoryAfterResolveData } from '@rspack/binding'; +import type { JsContextModuleFactoryBeforeResolveData } from '@rspack/binding'; import type { JsCreateData } from '@rspack/binding'; +import { JsDependency } from '@rspack/binding'; +import { JsDependencyMut } from '@rspack/binding'; import type { JsFactoryMeta } from '@rspack/binding'; import { JsHtmlPluginTag } from '@rspack/binding'; import { JsLibraryOptions } from '@rspack/binding'; @@ -518,9 +520,10 @@ const baseRuleSetRule: z.ZodObject<{ sideEffects: z.ZodOptional; enforce: z.ZodOptional, z.ZodLiteral<"post">]>>; }, "strict", z.ZodTypeAny, { + type?: string | undefined; + resource?: RuleSetCondition | undefined; layer?: string | undefined; options?: string | Record | undefined; - type?: string | undefined; loader?: string | undefined; test?: RuleSetCondition | undefined; exclude?: RuleSetCondition | undefined; @@ -528,7 +531,6 @@ const baseRuleSetRule: z.ZodObject<{ issuer?: RuleSetCondition | undefined; issuerLayer?: RuleSetCondition | undefined; dependency?: RuleSetCondition | undefined; - resource?: RuleSetCondition | undefined; resourceFragment?: RuleSetCondition | undefined; resourceQuery?: RuleSetCondition | undefined; scheme?: RuleSetCondition | undefined; @@ -554,9 +556,10 @@ const baseRuleSetRule: z.ZodObject<{ sideEffects?: boolean | undefined; enforce?: "pre" | "post" | undefined; }, { + type?: string | undefined; + resource?: RuleSetCondition | undefined; layer?: string | undefined; options?: string | Record | undefined; - type?: string | undefined; loader?: string | undefined; test?: RuleSetCondition | undefined; exclude?: RuleSetCondition | undefined; @@ -564,7 +567,6 @@ const baseRuleSetRule: z.ZodObject<{ issuer?: RuleSetCondition | undefined; issuerLayer?: RuleSetCondition | undefined; dependency?: RuleSetCondition | undefined; - resource?: RuleSetCondition | undefined; resourceFragment?: RuleSetCondition | undefined; resourceQuery?: RuleSetCondition | undefined; scheme?: RuleSetCondition | undefined; @@ -1372,38 +1374,45 @@ class ContextModuleFactory { // @public (undocumented) class ContextModuleFactoryAfterResolveData { - constructor(data: JsContextModuleFactoryAfterResolveData); // (undocumented) static __from_binding(binding: JsContextModuleFactoryAfterResolveData): ContextModuleFactoryAfterResolveData; // (undocumented) static __to_binding(data: ContextModuleFactoryAfterResolveData): JsContextModuleFactoryAfterResolveData; // (undocumented) - get context(): string; - set context(val: string); + context: string; // (undocumented) - get dependencies(): Dependency[]; + readonly dependencies: Dependency[]; // (undocumented) - get recursive(): boolean; - set recursive(val: boolean); + recursive: boolean; // (undocumented) - get regExp(): RegExp | undefined; - set regExp(val: RegExp | undefined); + regExp: RegExp | undefined; // (undocumented) - get request(): string; - set request(val: string); + request: string; // (undocumented) - get resource(): string; - set resource(val: string); + resource: number; } // @public (undocumented) type ContextModuleFactoryAfterResolveResult = false | ContextModuleFactoryAfterResolveData; // @public (undocumented) -type ContextModuleFactoryBeforeResolveResult = false | { +class ContextModuleFactoryBeforeResolveData { + // (undocumented) + static __from_binding(binding: JsContextModuleFactoryBeforeResolveData): ContextModuleFactoryBeforeResolveData; + // (undocumented) + static __to_binding(data: ContextModuleFactoryBeforeResolveData): JsContextModuleFactoryBeforeResolveData; + // (undocumented) context: string; - request?: string; -}; + // (undocumented) + recursive: boolean; + // (undocumented) + regExp: RegExp | undefined; + // (undocumented) + request: string; +} + +// @public (undocumented) +type ContextModuleFactoryBeforeResolveResult = false | ContextModuleFactoryBeforeResolveData; // @public (undocumented) export const ContextReplacementPlugin: { @@ -1658,13 +1667,16 @@ class DependenciesBlock { // @public (undocumented) class Dependency { - constructor(binding: DependencyDTO); // (undocumented) - get category(): string; + static __from_binding(binding: JsDependencyMut | JsDependency): Dependency; + // (undocumented) + readonly category: string; // (undocumented) - get request(): string | undefined; + critical: boolean; // (undocumented) - get type(): string; + readonly request: string | undefined; + // (undocumented) + readonly type: string; } // @public (undocumented) @@ -9390,16 +9402,16 @@ export const rspackOptions: z.ZodObject<{ issuer: string; }>>; }, "strict", z.ZodTypeAny, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -9415,16 +9427,16 @@ export const rspackOptions: z.ZodObject<{ issuer: string; }>>; }, "strict", z.ZodTypeAny, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -9440,16 +9452,16 @@ export const rspackOptions: z.ZodObject<{ issuer: string; }>>; }, "strict", z.ZodTypeAny, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -9465,16 +9477,16 @@ export const rspackOptions: z.ZodObject<{ issuer: string; }>>; }, "strict", z.ZodTypeAny, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -9841,10 +9853,10 @@ export const rspackOptions: z.ZodObject<{ type: z.ZodOptional]>>; idHint: z.ZodOptional; }, "strict", z.ZodTypeAny, { + type?: string | RegExp | undefined; filename?: string | undefined; name?: string | false | ((args_0: Module | undefined, ...args_1: unknown[]) => unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -9861,10 +9873,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; }, { + type?: string | RegExp | undefined; filename?: string | undefined; name?: string | false | ((args_0: Module | undefined, ...args_1: unknown[]) => unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -9918,10 +9930,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -9961,10 +9973,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -10034,10 +10046,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -10100,10 +10112,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -11157,6 +11169,8 @@ export const rspackOptions: z.ZodObject<{ maxEntrypointSize?: number | undefined; }>, z.ZodLiteral]>>; }, "strict", z.ZodTypeAny, { + context?: string | undefined; + dependencies?: string[] | undefined; module?: { parser?: { javascript?: { @@ -11302,9 +11316,7 @@ export const rspackOptions: z.ZodObject<{ defaultRules?: (false | "" | 0 | "..." | RuleSetRule | null | undefined)[] | undefined; noParse?: string | RegExp | ((args_0: string, ...args_1: unknown[]) => boolean) | (string | RegExp | ((args_0: string, ...args_1: unknown[]) => boolean))[] | undefined; } | undefined; - dependencies?: string[] | undefined; name?: string | undefined; - context?: string | undefined; performance?: false | { assetFilter?: ((args_0: string, ...args_1: unknown[]) => boolean) | undefined; hints?: false | "error" | "warning" | undefined; @@ -11547,30 +11559,30 @@ export const rspackOptions: z.ZodObject<{ } | undefined; } | undefined; externals?: string | RegExp | Record> | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, args_1: (args_0: Error | undefined, args_1: string | boolean | string[] | Record | undefined, args_2: "module" | "global" | "system" | "promise" | "commonjs" | "umd" | "amd" | "jsonp" | "import" | "var" | "assign" | "this" | "window" | "self" | "commonjs2" | "commonjs-module" | "commonjs-static" | "amd-require" | "umd2" | "module-import" | "script" | "node-commonjs" | undefined, ...args_3: unknown[]) => void, ...args_2: unknown[]) => unknown) | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, ...args_1: unknown[]) => Promise>) | (string | RegExp | Record> | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, args_1: (args_0: Error | undefined, args_1: string | boolean | string[] | Record | undefined, args_2: "module" | "global" | "system" | "promise" | "commonjs" | "umd" | "amd" | "jsonp" | "import" | "var" | "assign" | "this" | "window" | "self" | "commonjs2" | "commonjs-module" | "commonjs-static" | "amd-require" | "umd2" | "module-import" | "script" | "node-commonjs" | undefined, ...args_3: unknown[]) => void, ...args_2: unknown[]) => unknown) | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -11698,10 +11710,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; @@ -11755,6 +11767,8 @@ export const rspackOptions: z.ZodObject<{ devServer?: DevServer | undefined; bail?: boolean | undefined; }, { + context?: string | undefined; + dependencies?: string[] | undefined; module?: { parser?: { javascript?: { @@ -11900,9 +11914,7 @@ export const rspackOptions: z.ZodObject<{ defaultRules?: (false | "" | 0 | "..." | RuleSetRule | null | undefined)[] | undefined; noParse?: string | RegExp | ((args_0: string, ...args_1: unknown[]) => boolean) | (string | RegExp | ((args_0: string, ...args_1: unknown[]) => boolean))[] | undefined; } | undefined; - dependencies?: string[] | undefined; name?: string | undefined; - context?: string | undefined; performance?: false | { assetFilter?: ((args_0: string, ...args_1: unknown[]) => boolean) | undefined; hints?: false | "error" | "warning" | undefined; @@ -12145,30 +12157,30 @@ export const rspackOptions: z.ZodObject<{ } | undefined; } | undefined; externals?: string | RegExp | Record> | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, args_1: (args_0: Error | undefined, args_1: string | boolean | string[] | Record | undefined, args_2: "module" | "global" | "system" | "promise" | "commonjs" | "umd" | "amd" | "jsonp" | "import" | "var" | "assign" | "this" | "window" | "self" | "commonjs2" | "commonjs-module" | "commonjs-static" | "amd-require" | "umd2" | "module-import" | "script" | "node-commonjs" | undefined, ...args_3: unknown[]) => void, ...args_2: unknown[]) => unknown) | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, ...args_1: unknown[]) => Promise>) | (string | RegExp | Record> | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; }, args_1: (args_0: Error | undefined, args_1: string | boolean | string[] | Record | undefined, args_2: "module" | "global" | "system" | "promise" | "commonjs" | "umd" | "amd" | "jsonp" | "import" | "var" | "assign" | "this" | "window" | "self" | "commonjs2" | "commonjs-module" | "commonjs-static" | "amd-require" | "umd2" | "module-import" | "script" | "node-commonjs" | undefined, ...args_3: unknown[]) => void, ...args_2: unknown[]) => unknown) | ((args_0: { + request?: string | undefined; context?: string | undefined; dependencyType?: string | undefined; - request?: string | undefined; contextInfo?: { issuer: string; } | undefined; @@ -12296,10 +12308,10 @@ export const rspackOptions: z.ZodObject<{ maxInitialRequests?: number | undefined; automaticNameDelimiter?: string | undefined; cacheGroups?: Record unknown) | undefined; priority?: number | undefined; - type?: string | RegExp | undefined; chunks?: RegExp | "async" | "all" | "initial" | ((args_0: Chunk, ...args_1: unknown[]) => boolean) | undefined; usedExports?: boolean | undefined; test?: string | RegExp | ((args_0: Module, ...args_1: unknown[]) => unknown) | undefined; diff --git a/packages/rspack/src/Compiler.ts b/packages/rspack/src/Compiler.ts index 19c0102f97c..009085bc752 100644 --- a/packages/rspack/src/Compiler.ts +++ b/packages/rspack/src/Compiler.ts @@ -33,6 +33,7 @@ import { ThreadsafeWritableNodeFS } from "./FileSystem"; import { CodeGenerationResult, ContextModuleFactoryAfterResolveData, + ContextModuleFactoryBeforeResolveData, Module } from "./Module"; import { NormalModuleFactory } from "./NormalModuleFactory"; @@ -1163,7 +1164,15 @@ class Compiler { | false | binding.JsContextModuleFactoryBeforeResolveData ) => { - return queried.promise(bindingData); + const data = bindingData + ? ContextModuleFactoryBeforeResolveData.__from_binding( + bindingData + ) + : false; + const result = await queried.promise(data); + return result + ? ContextModuleFactoryBeforeResolveData.__to_binding(result) + : false; } ), registerContextModuleFactoryAfterResolveTaps: @@ -1182,11 +1191,10 @@ class Compiler { bindingData ) : false; - const ret = await queried.promise(data); - const result = ret - ? ContextModuleFactoryAfterResolveData.__to_binding(ret) + const result = await queried.promise(data); + return result + ? ContextModuleFactoryAfterResolveData.__to_binding(result) : false; - return result; } ), registerJavascriptModulesChunkHashTaps: this.#createHookRegisterTaps( diff --git a/packages/rspack/src/DependenciesBlock.ts b/packages/rspack/src/DependenciesBlock.ts index 452d63bd62c..7879c43ebd7 100644 --- a/packages/rspack/src/DependenciesBlock.ts +++ b/packages/rspack/src/DependenciesBlock.ts @@ -9,7 +9,7 @@ export class DependenciesBlock { } get dependencies(): Dependency[] { - return this.#binding.dependencies.map(d => new Dependency(d)); + return this.#binding.dependencies.map(d => Dependency.__from_binding(d)); } get blocks(): DependenciesBlock[] { diff --git a/packages/rspack/src/Dependency.ts b/packages/rspack/src/Dependency.ts index d0aacf04701..49e3eb5b3ef 100644 --- a/packages/rspack/src/Dependency.ts +++ b/packages/rspack/src/Dependency.ts @@ -1,21 +1,46 @@ -import type { DependencyDTO } from "@rspack/binding"; +import { type JsDependency, JsDependencyMut } from "@rspack/binding"; export class Dependency { - #binding: DependencyDTO; + declare readonly type: string; + declare readonly category: string; + declare readonly request: string | undefined; + declare critical: boolean; - constructor(binding: DependencyDTO) { - this.#binding = binding; + static __from_binding(binding: JsDependencyMut | JsDependency): Dependency { + return new Dependency(binding); } - get type(): string { - return this.#binding.type; - } - - get category(): string { - return this.#binding.category; - } - - get request(): string | undefined { - return this.#binding.request; + private constructor(binding: JsDependencyMut | JsDependency) { + Object.defineProperties(this, { + type: { + enumerable: true, + get(): string { + return binding.type; + } + }, + category: { + enumerable: true, + get(): string { + return binding.category; + } + }, + request: { + enumerable: true, + get(): string | undefined { + return binding.request; + } + }, + critical: { + enumerable: true, + get(): boolean { + return binding.critical; + }, + set(val: boolean) { + if (binding instanceof JsDependencyMut) { + binding.critical = val; + } + } + } + }); } } diff --git a/packages/rspack/src/Module.ts b/packages/rspack/src/Module.ts index a83e3dbf2ec..e978e1565e6 100644 --- a/packages/rspack/src/Module.ts +++ b/packages/rspack/src/Module.ts @@ -1,6 +1,7 @@ import type { JsCodegenerationResult, JsContextModuleFactoryAfterResolveData, + JsContextModuleFactoryBeforeResolveData, JsCreateData, JsFactoryMeta, JsModule, @@ -10,7 +11,7 @@ import type { Source } from "webpack-sources"; import type { Compilation } from "./Compilation"; import { DependenciesBlock } from "./DependenciesBlock"; -import type { Dependency } from "./Dependency"; +import { Dependency } from "./Dependency"; import { JsSource } from "./util/source"; export type ResourceData = { @@ -36,82 +37,172 @@ export type ResolveData = { createData?: CreateData; }; -export type ContextModuleFactoryBeforeResolveResult = - | false - | { - context: string; - request?: string; - }; +export class ContextModuleFactoryBeforeResolveData { + #inner: JsContextModuleFactoryBeforeResolveData; -export class ContextModuleFactoryAfterResolveData { - #inner: JsContextModuleFactoryAfterResolveData; + declare context: string; + declare request: string; + declare regExp: RegExp | undefined; + declare recursive: boolean; - static __from_binding(binding: JsContextModuleFactoryAfterResolveData) { - return new ContextModuleFactoryAfterResolveData(binding); + static __from_binding(binding: JsContextModuleFactoryBeforeResolveData) { + return new ContextModuleFactoryBeforeResolveData(binding); } - static __to_binding(data: ContextModuleFactoryAfterResolveData) { + static __to_binding( + data: ContextModuleFactoryBeforeResolveData + ): JsContextModuleFactoryBeforeResolveData { return data.#inner; } - constructor(data: JsContextModuleFactoryAfterResolveData) { - this.#inner = data; - } - - get resource(): string { - return this.#inner.resource; - } - - set resource(val: string) { - this.#inner.resource = val; - } - - get context(): string { - return this.#inner.context; - } - - set context(val: string) { - this.#inner.context = val; - } - - get request(): string { - return this.#inner.request; + private constructor(binding: JsContextModuleFactoryBeforeResolveData) { + this.#inner = binding; + + Object.defineProperties(this, { + context: { + enumerable: true, + get(): string { + return binding.context; + }, + set(val: string) { + binding.context = val; + } + }, + request: { + enumerable: true, + get(): string { + return binding.request; + }, + set(val: string) { + binding.request = val; + } + }, + regExp: { + enumerable: true, + get(): RegExp | undefined { + if (!binding.regExp) { + return undefined; + } + const { source, flags } = binding.regExp; + return new RegExp(source, flags); + }, + set(val: RegExp | undefined) { + if (!val) { + binding.regExp = undefined; + return; + } + binding.regExp = { + source: val.source, + flags: val.flags + }; + } + }, + recursive: { + enumerable: true, + get(this: ContextModuleFactoryAfterResolveData): boolean { + return binding.recursive; + }, + set(val: boolean) { + binding.recursive = val; + } + } + }); } +} - set request(val: string) { - this.#inner.request = val; - } +export type ContextModuleFactoryBeforeResolveResult = + | false + | ContextModuleFactoryBeforeResolveData; - get regExp(): RegExp | undefined { - if (!this.#inner.regExp) { - return undefined; - } - const { source, flags } = this.#inner.regExp; - return new RegExp(source, flags); - } +export class ContextModuleFactoryAfterResolveData { + #inner: JsContextModuleFactoryAfterResolveData; - set regExp(val: RegExp | undefined) { - if (!val) { - this.#inner.regExp = undefined; - return; - } - this.#inner.regExp = { - source: val.source, - flags: val.flags - }; - } + declare resource: number; + declare context: string; + declare request: string; + declare regExp: RegExp | undefined; + declare recursive: boolean; + declare readonly dependencies: Dependency[]; - get recursive(): boolean { - return this.#inner.recursive; + static __from_binding(binding: JsContextModuleFactoryAfterResolveData) { + return new ContextModuleFactoryAfterResolveData(binding); } - set recursive(val: boolean) { - this.#inner.recursive = val; + static __to_binding( + data: ContextModuleFactoryAfterResolveData + ): JsContextModuleFactoryAfterResolveData { + return data.#inner; } - get dependencies(): Dependency[] { - // TODO: Dependencies are not fully supported yet; this is a placeholder to prevent errors in moment-locales-webpack-plugin. - return []; + private constructor(binding: JsContextModuleFactoryAfterResolveData) { + this.#inner = binding; + + Object.defineProperties(this, { + resource: { + enumerable: true, + get(): string { + return binding.resource; + }, + set(val: string) { + binding.resource = val; + } + }, + context: { + enumerable: true, + get(): string { + return binding.context; + }, + set(val: string) { + binding.context = val; + } + }, + request: { + enumerable: true, + get(): string { + return binding.request; + }, + set(val: string) { + binding.request = val; + } + }, + regExp: { + enumerable: true, + get(): RegExp | undefined { + if (!binding.regExp) { + return undefined; + } + const { source, flags } = binding.regExp; + return new RegExp(source, flags); + }, + set(val: RegExp | undefined) { + if (!val) { + binding.regExp = undefined; + return; + } + binding.regExp = { + source: val.source, + flags: val.flags + }; + } + }, + recursive: { + enumerable: true, + get(): boolean { + return binding.recursive; + }, + set(val: boolean) { + binding.recursive = val; + } + }, + dependencies: { + enumerable: true, + get(): Dependency[] { + return binding.dependencies.map(dep => + Dependency.__from_binding(dep) + ); + } + } + }); } }