Skip to content

Commit 3836042

Browse files
authored
feat: support getResolve in external function context (#8577)
1 parent c1ffe56 commit 3836042

File tree

25 files changed

+238
-216
lines changed

25 files changed

+238
-216
lines changed

crates/node_binding/binding.d.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ export declare class JsStats {
205205
getLogging(acceptedTypes: number): Array<JsStatsLogging>
206206
}
207207

208+
export declare class RawExternalItemFnCtx {
209+
data(): RawExternalItemFnCtxData
210+
getResolver(): JsResolver
211+
}
212+
208213
export declare class Rspack {
209214
constructor(options: RawOptions, builtinPlugins: Array<BuiltinPlugin>, registerJsTaps: RegisterJsTaps, outputFilesystem: ThreadsafeNodeFS, resolverFactoryReference: JsResolverFactory)
210215
setNonSkippableRegisters(kinds: Array<RegisterJsTapKind>): void
@@ -1397,7 +1402,7 @@ export interface RawExposeOptions {
13971402
import: Array<string>
13981403
}
13991404

1400-
export interface RawExternalItemFnCtx {
1405+
export interface RawExternalItemFnCtxData {
14011406
request: string
14021407
context: string
14031408
dependencyType: string

crates/rspack_binding_options/src/options/raw_external.rs

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use std::collections::HashMap;
22
use std::fmt::Debug;
3+
use std::sync::Arc;
34

45
use napi::bindgen_prelude::Either4;
56
use napi_derive::napi;
6-
use rspack_core::ExternalItemFnCtx;
7+
use rspack_binding_values::JsResolver;
78
use rspack_core::{ExternalItem, ExternalItemFnResult, ExternalItemValue};
9+
use rspack_core::{ExternalItemFnCtx, ResolveOptionsWithDependencyType, ResolverFactory};
810
use rspack_napi::threadsafe_function::ThreadsafeFunction;
911
use rspack_regex::RspackRegex;
1012

@@ -68,15 +70,47 @@ pub struct ContextInfo {
6870
pub issuer: String,
6971
}
7072

71-
#[derive(Debug, Clone)]
72-
#[napi(object)]
73+
#[derive(Debug)]
74+
#[napi]
7375
pub struct RawExternalItemFnCtx {
76+
request: String,
77+
context: String,
78+
dependency_type: String,
79+
context_info: ContextInfo,
80+
resolve_options_with_dependency_type: ResolveOptionsWithDependencyType,
81+
resolver_factory: Arc<ResolverFactory>,
82+
}
83+
84+
#[derive(Debug)]
85+
#[napi(object)]
86+
pub struct RawExternalItemFnCtxData {
7487
pub request: String,
7588
pub context: String,
7689
pub dependency_type: String,
7790
pub context_info: ContextInfo,
7891
}
7992

93+
#[napi]
94+
impl RawExternalItemFnCtx {
95+
#[napi]
96+
pub fn data(&self) -> RawExternalItemFnCtxData {
97+
RawExternalItemFnCtxData {
98+
request: self.request.clone(),
99+
context: self.context.clone(),
100+
dependency_type: self.dependency_type.clone(),
101+
context_info: self.context_info.clone(),
102+
}
103+
}
104+
105+
#[napi]
106+
pub fn get_resolver(&self) -> JsResolver {
107+
JsResolver::new(
108+
self.resolver_factory.clone(),
109+
self.resolve_options_with_dependency_type.clone(),
110+
)
111+
}
112+
}
113+
80114
impl From<ExternalItemFnCtx> for RawExternalItemFnCtx {
81115
fn from(value: ExternalItemFnCtx) -> Self {
82116
Self {
@@ -86,6 +120,8 @@ impl From<ExternalItemFnCtx> for RawExternalItemFnCtx {
86120
context_info: ContextInfo {
87121
issuer: value.context_info.issuer,
88122
},
123+
resolve_options_with_dependency_type: value.resolve_options_with_dependency_type,
124+
resolver_factory: value.resolver_factory,
89125
}
90126
}
91127
}

crates/rspack_binding_values/src/resolver.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::raw_resolve::{
1010
};
1111

1212
#[napi]
13+
#[derive(Debug)]
1314
pub struct JsResolver {
1415
resolver_factory: Arc<ResolverFactory>,
1516
resolver: Arc<Resolver>,

crates/rspack_core/src/compiler/make/repair/factorize.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
utils::task_loop::{Task, TaskResult, TaskType},
1212
BoxDependency, CompilationId, CompilerOptions, Context, ExportInfoData, ExportsInfoData,
1313
ModuleFactory, ModuleFactoryCreateData, ModuleFactoryResult, ModuleIdentifier, ModuleLayer,
14-
ModuleProfile, Resolve,
14+
ModuleProfile, Resolve, ResolverFactory,
1515
};
1616

1717
#[derive(Debug)]
@@ -24,9 +24,10 @@ pub struct FactorizeTask {
2424
pub issuer: Option<Box<str>>,
2525
pub issuer_layer: Option<ModuleLayer>,
2626
pub dependencies: Vec<BoxDependency>,
27-
pub resolve_options: Option<Box<Resolve>>,
27+
pub resolve_options: Option<Arc<Resolve>>,
2828
pub options: Arc<CompilerOptions>,
2929
pub current_profile: Option<Box<ModuleProfile>>,
30+
pub resolver_factory: Arc<ResolverFactory>,
3031
}
3132

3233
#[async_trait::async_trait]
@@ -89,6 +90,7 @@ impl Task<MakeTaskContext> for FactorizeTask {
8990
issuer: self.issuer,
9091
issuer_identifier: self.original_module_identifier,
9192
issuer_layer,
93+
resolver_factory: self.resolver_factory,
9294

9395
file_dependencies: Default::default(),
9496
missing_dependencies: Default::default(),

crates/rspack_core/src/compiler/make/repair/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub async fn repair(
142142
resolve_options: parent_module.and_then(|module| module.get_resolve_options()),
143143
options: compilation.options.clone(),
144144
current_profile,
145+
resolver_factory: compilation.resolver_factory.clone(),
145146
}))
146147
})
147148
.collect::<Vec<_>>();

crates/rspack_core/src/compiler/make/repair/process_dependencies.rs

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl Task<MakeTaskContext> for ProcessDependenciesTask {
109109
resolve_options: module.get_resolve_options(),
110110
options: context.compiler_options.clone(),
111111
current_profile,
112+
resolver_factory: context.resolver_factory.clone(),
112113
}));
113114
}
114115
Ok(res)

crates/rspack_core/src/compiler/module_executor/entry.rs

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ impl Task<MakeTaskContext> for EntryTask {
4545
.compiler_options
4646
.profile
4747
.then(Box::<ModuleProfile>::default),
48+
resolver_factory: context.resolver_factory.clone(),
4849
})])
4950
}
5051
}

crates/rspack_core/src/concatenated_module.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub struct RootModuleContext {
6464
pub readable_identifier: String,
6565
pub name_for_condition: Option<Box<str>>,
6666
pub lib_indent: Option<String>,
67-
pub resolve_options: Option<Box<Resolve>>,
67+
pub resolve_options: Option<Arc<Resolve>>,
6868
pub code_generation_dependencies: Option<Vec<Box<dyn ModuleDependency>>>,
6969
pub presentational_dependencies: Option<Vec<Box<dyn DependencyTemplate>>>,
7070
pub context: Option<Context>,
@@ -1361,7 +1361,7 @@ impl Module for ConcatenatedModule {
13611361
self.root_module_ctxt.lib_indent.clone().map(Cow::Owned)
13621362
}
13631363

1364-
fn get_resolve_options(&self) -> Option<Box<Resolve>> {
1364+
fn get_resolve_options(&self) -> Option<Arc<Resolve>> {
13651365
self.root_module_ctxt.resolve_options.clone()
13661366
}
13671367

crates/rspack_core/src/context_module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub struct ContextModuleOptions {
136136
pub resource_fragment: String,
137137
pub context_options: ContextOptions,
138138
pub layer: Option<ModuleLayer>,
139-
pub resolve_options: Option<Box<Resolve>>,
139+
pub resolve_options: Option<Arc<Resolve>>,
140140
pub type_prefix: ContextTypePrefix,
141141
}
142142

crates/rspack_core/src/context_module_factory.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ impl ContextModuleFactory {
125125
tracing::trace!("resolving context module path {}", options.resource);
126126

127127
let resolver = &resolver_factory.get(ResolveOptionsWithDependencyType {
128-
resolve_options: options.resolve_options.clone(),
128+
resolve_options: options
129+
.resolve_options
130+
.clone()
131+
.map(|r| Box::new(Arc::unwrap_or_clone(r))),
129132
resolve_to_context: false,
130133
dependency_category: options.context_options.category,
131134
});

crates/rspack_core/src/module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ pub trait Module:
329329
/// Resolve options matched by module rules.
330330
/// e.g `javascript/esm` may have special resolving options like `fullySpecified`.
331331
/// `css` and `css/module` may have special resolving options like `preferRelative`.
332-
fn get_resolve_options(&self) -> Option<Box<Resolve>> {
332+
fn get_resolve_options(&self) -> Option<Arc<Resolve>> {
333333
None
334334
}
335335

crates/rspack_core/src/module_factory.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ use rustc_hash::FxHashSet as HashSet;
66

77
use crate::{
88
BoxDependency, BoxModule, CompilationId, CompilerOptions, Context, ModuleIdentifier, ModuleLayer,
9-
Resolve,
9+
Resolve, ResolverFactory,
1010
};
1111

1212
#[derive(Debug, Clone)]
1313
pub struct ModuleFactoryCreateData {
1414
pub compilation_id: CompilationId,
15-
pub resolve_options: Option<Box<Resolve>>,
15+
pub resolve_options: Option<Arc<Resolve>>,
1616
pub options: Arc<CompilerOptions>,
1717
pub context: Context,
1818
pub dependencies: Vec<BoxDependency>,
1919
pub issuer: Option<Box<str>>,
2020
pub issuer_identifier: Option<ModuleIdentifier>,
2121
pub issuer_layer: Option<ModuleLayer>,
22+
pub resolver_factory: Arc<ResolverFactory>,
2223

2324
pub file_dependencies: HashSet<ArcPath>,
2425
pub context_dependencies: HashSet<ArcPath>,

crates/rspack_core/src/normal_module.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub struct NormalModule {
127127
source: NormalModuleSource,
128128

129129
/// Resolve options derived from [Rule.resolve]
130-
resolve_options: Option<Box<Resolve>>,
130+
resolve_options: Option<Arc<Resolve>>,
131131
/// Parser options derived from [Rule.parser]
132132
parser_options: Option<ParserOptions>,
133133
/// Generator options derived from [Rule.generator]
@@ -197,7 +197,7 @@ impl NormalModule {
197197
generator_options: Option<GeneratorOptions>,
198198
match_resource: Option<ResourceData>,
199199
resource_data: Arc<ResourceData>,
200-
resolve_options: Option<Box<Resolve>>,
200+
resolve_options: Option<Arc<Resolve>>,
201201
loaders: Vec<BoxLoader>,
202202
) -> Self {
203203
let module_type = module_type.into();
@@ -720,7 +720,7 @@ impl Module for NormalModule {
720720
Some(Cow::Owned(ident))
721721
}
722722

723-
fn get_resolve_options(&self) -> Option<Box<Resolve>> {
723+
fn get_resolve_options(&self) -> Option<Arc<Resolve>> {
724724
self.resolve_options.clone()
725725
}
726726

crates/rspack_core/src/normal_module_factory.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl NormalModuleFactory {
329329
span: dependency_source_span,
330330
// take the options is safe here, because it
331331
// is not used in after_resolve hooks
332-
resolve_options: data.resolve_options.take(),
332+
resolve_options: data.resolve_options.clone(),
333333
resolve_to_context: false,
334334
optional: dependency_optional,
335335
file_dependencies: &mut file_dependencies,
@@ -641,7 +641,7 @@ impl NormalModuleFactory {
641641
Ok(rules)
642642
}
643643

644-
fn calculate_resolve_options(&self, module_rules: &[&ModuleRuleEffect]) -> Option<Box<Resolve>> {
644+
fn calculate_resolve_options(&self, module_rules: &[&ModuleRuleEffect]) -> Option<Arc<Resolve>> {
645645
let mut resolved: Option<Resolve> = None;
646646
for rule in module_rules {
647647
if let Some(rule_resolve) = &rule.resolve {
@@ -652,7 +652,7 @@ impl NormalModuleFactory {
652652
}
653653
}
654654
}
655-
resolved.map(Box::new)
655+
resolved.map(Arc::new)
656656
}
657657

658658
fn calculate_side_effects(&self, module_rules: &[&ModuleRuleEffect]) -> Option<bool> {

crates/rspack_core/src/options/externals.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use std::fmt::Debug;
1+
use std::{fmt::Debug, sync::Arc};
22

33
use futures::future::BoxFuture;
44
use rspack_error::Result;
55
use rspack_regex::RspackRegex;
66
use rustc_hash::FxHashMap as HashMap;
77

8+
use crate::{ResolveOptionsWithDependencyType, ResolverFactory};
9+
810
pub type Externals = Vec<ExternalItem>;
911

1012
#[derive(Debug)]
@@ -26,6 +28,8 @@ pub struct ExternalItemFnCtx {
2628
pub context: String,
2729
pub dependency_type: String,
2830
pub context_info: ContextInfo,
31+
pub resolve_options_with_dependency_type: ResolveOptionsWithDependencyType,
32+
pub resolver_factory: Arc<ResolverFactory>,
2933
}
3034

3135
pub struct ExternalItemFnResult {

crates/rspack_core/src/resolver/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::borrow::Borrow;
55
use std::fmt;
66
use std::fs;
77
use std::path::PathBuf;
8+
use std::sync::Arc;
89
use std::sync::LazyLock;
910

1011
use regex::Regex;
@@ -41,7 +42,7 @@ pub struct ResolveArgs<'a> {
4142
pub dependency_type: &'a DependencyType,
4243
pub dependency_category: &'a DependencyCategory,
4344
pub span: Option<ErrorSpan>,
44-
pub resolve_options: Option<Box<Resolve>>,
45+
pub resolve_options: Option<Arc<Resolve>>,
4546
pub resolve_to_context: bool,
4647
pub optional: bool,
4748
pub file_dependencies: &'a mut FxHashSet<PathBuf>,
@@ -94,7 +95,9 @@ pub fn resolve_for_error_hints(
9495
plugin_driver: &SharedPluginDriver,
9596
) -> Option<String> {
9697
let dep = ResolveOptionsWithDependencyType {
97-
resolve_options: args.resolve_options.clone(),
98+
resolve_options: args
99+
.resolve_options
100+
.map(|r| Box::new(Arc::unwrap_or_clone(r))),
98101
resolve_to_context: args.resolve_to_context,
99102
dependency_category: *args.dependency_category,
100103
};
@@ -284,7 +287,10 @@ pub async fn resolve(
284287
plugin_driver: &SharedPluginDriver,
285288
) -> Result<ResolveResult, Error> {
286289
let dep = ResolveOptionsWithDependencyType {
287-
resolve_options: args.resolve_options.clone(),
290+
resolve_options: args
291+
.resolve_options
292+
.clone()
293+
.map(|r| Box::new(Arc::unwrap_or_clone(r))),
288294
resolve_to_context: args.resolve_to_context,
289295
dependency_category: *args.dependency_category,
290296
};

crates/rspack_plugin_externals/src/plugin.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use std::fmt::Debug;
21
use std::sync::LazyLock;
2+
use std::{fmt::Debug, sync::Arc};
33

44
use regex::Regex;
55
use rspack_core::{
66
ApplyContext, BoxModule, CompilerOptions, ContextInfo, DependencyMeta, ExternalItem,
77
ExternalItemFnCtx, ExternalItemValue, ExternalModule, ExternalRequest, ExternalRequestValue,
88
ExternalType, ExternalTypeEnum, ModuleDependency, ModuleExt, ModuleFactoryCreateData,
9-
NormalModuleFactoryFactorize, Plugin, PluginContext,
9+
NormalModuleFactoryFactorize, Plugin, PluginContext, ResolveOptionsWithDependencyType,
1010
};
1111
use rspack_error::Result;
1212
use rspack_hook::{plugin, plugin_hook};
@@ -182,6 +182,19 @@ async fn factorize(&self, data: &mut ModuleFactoryCreateData) -> Result<Option<B
182182
.clone()
183183
.map_or("".to_string(), |i| i.to_string()),
184184
},
185+
resolve_options_with_dependency_type: ResolveOptionsWithDependencyType {
186+
resolve_options: data
187+
.resolve_options
188+
.clone()
189+
.map(|r| Box::new(Arc::unwrap_or_clone(r))),
190+
resolve_to_context: false,
191+
dependency_category: *data
192+
.dependencies
193+
.first()
194+
.expect("Expected at least one dependency")
195+
.category(),
196+
},
197+
resolver_factory: data.resolver_factory.clone(),
185198
})
186199
.await?;
187200
if let Some(r) = result.result {

crates/rspack_plugin_lazy_compilation/src/factory.rs

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl ModuleFactory for LazyCompilationDependencyFactory {
4141
issuer: proxy_data.issuer.clone(),
4242
issuer_layer: proxy_data.issuer_layer.clone(),
4343
issuer_identifier: proxy_data.issuer_identifier,
44+
resolver_factory: proxy_data.resolver_factory.clone(),
4445
file_dependencies: proxy_data.file_dependencies.clone(),
4546
context_dependencies: proxy_data.context_dependencies.clone(),
4647
missing_dependencies: proxy_data.missing_dependencies.clone(),

0 commit comments

Comments
 (0)