Skip to content

Commit c5f1697

Browse files
authored
feat: support option resolveLoader (#4008)
* feat: support option `resolveLoader` * fix: fix resolve issue * fix: test * chore: lint * chore: skip test
1 parent 02f09d2 commit c5f1697

File tree

25 files changed

+185
-59
lines changed

25 files changed

+185
-59
lines changed

crates/node_binding/binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ export interface RawOptions {
814814
context: string
815815
output: RawOutputOptions
816816
resolve: RawResolveOptions
817+
resolveLoader: RawResolveOptions
817818
module: RawModuleOptions
818819
builtins: RawBuiltins
819820
externals?: Array<RawExternalItem>

crates/node_binding/src/plugins/loader.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ impl Plugin for JsLoaderResolver {
8080

8181
match resolve_result {
8282
ResolveResult::Resource(resource) => {
83+
// TODO: Should move this logic to `resolver`, since `resolve.alias` may contain query or fragment too. @Boshen
8384
let resource = resource.path.to_string_lossy().to_string() + rest.unwrap_or_default();
8485
Ok(Some(Arc::new(JsLoaderAdapter {
8586
identifier: resource.into(),

crates/rspack_binding_options/src/options/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub struct RawOptions {
6767
pub context: RawContext,
6868
pub output: RawOutputOptions,
6969
pub resolve: RawResolveOptions,
70+
pub resolve_loader: RawResolveOptions,
7071
pub module: RawModuleOptions,
7172
pub builtins: RawBuiltins,
7273
pub externals: Option<Vec<RawExternalItem>>,
@@ -115,6 +116,7 @@ impl RawOptionsApply for RawOptions {
115116
}
116117
let output: OutputOptions = self.output.apply(plugins)?;
117118
let resolve = self.resolve.try_into()?;
119+
let resolve_loader = self.resolve_loader.try_into()?;
118120
let devtool: Devtool = self.devtool.into();
119121
let mode = self.mode.unwrap_or_default().into();
120122
let module: ModuleOptions = self.module.apply(plugins)?;
@@ -253,6 +255,7 @@ impl RawOptionsApply for RawOptions {
253255
target,
254256
output,
255257
resolve,
258+
resolve_loader,
256259
devtool,
257260
experiments,
258261
stats,

crates/rspack_core/src/compiler/compilation.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub struct Compilation {
7676
logging: CompilationLogging,
7777
pub plugin_driver: SharedPluginDriver,
7878
pub resolver_factory: Arc<ResolverFactory>,
79+
pub loader_resolver_factory: Arc<ResolverFactory>,
7980
pub named_chunks: HashMap<String, ChunkUkey>,
8081
pub(crate) named_chunk_groups: HashMap<String, ChunkGroupUkey>,
8182
pub entry_module_identifiers: IdentifierSet,
@@ -110,6 +111,7 @@ impl Compilation {
110111
module_graph: ModuleGraph,
111112
plugin_driver: SharedPluginDriver,
112113
resolver_factory: Arc<ResolverFactory>,
114+
loader_resolver_factory: Arc<ResolverFactory>,
113115
cache: Arc<Cache>,
114116
) -> Self {
115117
Self {
@@ -133,6 +135,7 @@ impl Compilation {
133135
logging: Default::default(),
134136
plugin_driver,
135137
resolver_factory,
138+
loader_resolver_factory,
136139
named_chunks: Default::default(),
137140
named_chunk_groups: Default::default(),
138141
entry_module_identifiers: IdentifierSet::default(),
@@ -875,6 +878,7 @@ impl Compilation {
875878
resolve_options,
876879
lazy_visit_modules,
877880
resolver_factory: self.resolver_factory.clone(),
881+
loader_resolver_factory: self.loader_resolver_factory.clone(),
878882
options: self.options.clone(),
879883
plugin_driver: self.plugin_driver.clone(),
880884
cache: self.cache.clone(),

crates/rspack_core/src/compiler/hmr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ where
134134
Default::default(),
135135
self.plugin_driver.clone(),
136136
self.resolver_factory.clone(),
137+
self.loader_resolver_factory.clone(),
137138
self.cache.clone(),
138139
);
139140

crates/rspack_core/src/compiler/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ where
3737
pub compilation: Compilation,
3838
pub plugin_driver: SharedPluginDriver,
3939
pub resolver_factory: Arc<ResolverFactory>,
40+
pub loader_resolver_factory: Arc<ResolverFactory>,
4041
pub cache: Arc<Cache>,
4142
/// emitted asset versions
4243
/// the key of HashMap is filename, the value of HashMap is version
@@ -56,6 +57,7 @@ where
5657
let options = Arc::new(options);
5758

5859
let resolver_factory = Arc::new(ResolverFactory::new(options.resolve.clone()));
60+
let loader_resolver_factory = Arc::new(ResolverFactory::new(options.resolve_loader.clone()));
5961
let plugin_driver = Arc::new(PluginDriver::new(
6062
options.clone(),
6163
plugins,
@@ -70,11 +72,13 @@ where
7072
Default::default(),
7173
plugin_driver.clone(),
7274
resolver_factory.clone(),
75+
loader_resolver_factory.clone(),
7376
cache.clone(),
7477
),
7578
output_filesystem,
7679
plugin_driver,
7780
resolver_factory,
81+
loader_resolver_factory,
7882
cache,
7983
emitted_asset_versions: Default::default(),
8084
}
@@ -99,6 +103,7 @@ where
99103
Default::default(),
100104
self.plugin_driver.clone(),
101105
self.resolver_factory.clone(),
106+
self.loader_resolver_factory.clone(),
102107
self.cache.clone(),
103108
),
104109
);

crates/rspack_core/src/compiler/queue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub struct FactorizeTask {
3333
pub side_effects: Option<bool>,
3434
pub resolve_options: Option<Resolve>,
3535
pub resolver_factory: Arc<ResolverFactory>,
36+
pub loader_resolver_factory: Arc<ResolverFactory>,
3637
pub options: Arc<CompilerOptions>,
3738
pub lazy_visit_modules: std::collections::HashSet<String>,
3839
pub plugin_driver: SharedPluginDriver,
@@ -92,7 +93,7 @@ impl WorkerTask for FactorizeTask {
9293
lazy_visit_modules: self.lazy_visit_modules,
9394
issuer: self.issuer,
9495
},
95-
self.resolver_factory,
96+
self.loader_resolver_factory,
9697
self.plugin_driver,
9798
self.cache,
9899
);

crates/rspack_core/src/normal_module_factory.rs

Lines changed: 100 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ use rspack_error::{
66
internal_error, Diagnostic, IntoTWithDiagnosticArray, Result, TWithDiagnosticArray,
77
};
88
use rspack_identifier::Identifiable;
9-
use rspack_loader_runner::{get_scheme, DescriptionData, Scheme};
9+
use rspack_loader_runner::{get_scheme, DescriptionData, Loader, Scheme};
1010
use sugar_path::{AsPath, SugarPath};
1111
use swc_core::common::Span;
1212

1313
use crate::{
1414
cache::Cache,
1515
module_rules_matcher, parse_resource, resolve, stringify_loaders_and_resource,
1616
tree_shaking::visitor::{get_side_effects_from_package_json, SideEffects},
17-
BoxLoader, CompilerOptions, DependencyCategory, DependencyType, FactorizeArgs, FactoryMeta,
18-
FuncUseCtx, GeneratorOptions, MissingModule, ModuleArgs, ModuleExt, ModuleFactory,
17+
BoxLoader, CompilerContext, CompilerOptions, DependencyCategory, DependencyType, FactorizeArgs,
18+
FactoryMeta, FuncUseCtx, GeneratorOptions, MissingModule, ModuleArgs, ModuleExt, ModuleFactory,
1919
ModuleFactoryCreateData, ModuleFactoryResult, ModuleIdentifier, ModuleRule, ModuleRuleEnforce,
2020
ModuleRuleUse, ModuleRuleUseLoader, ModuleType, NormalModule, NormalModuleAfterResolveArgs,
2121
NormalModuleBeforeResolveArgs, ParserOptions, RawModule, Resolve, ResolveArgs, ResolveError,
@@ -26,7 +26,7 @@ use crate::{
2626
#[derive(Debug)]
2727
pub struct NormalModuleFactory {
2828
context: NormalModuleFactoryContext,
29-
resolver_factory: Arc<ResolverFactory>,
29+
loader_resolver_factory: Arc<ResolverFactory>,
3030
plugin_driver: SharedPluginDriver,
3131
cache: Arc<Cache>,
3232
}
@@ -55,13 +55,13 @@ static MATCH_RESOURCE_REGEX: Lazy<Regex> =
5555
impl NormalModuleFactory {
5656
pub fn new(
5757
context: NormalModuleFactoryContext,
58-
resolver_factory: Arc<ResolverFactory>,
58+
loader_resolver_factory: Arc<ResolverFactory>,
5959
plugin_driver: SharedPluginDriver,
6060
cache: Arc<Cache>,
6161
) -> Self {
6262
Self {
6363
context,
64-
resolver_factory,
64+
loader_resolver_factory,
6565
plugin_driver,
6666
cache,
6767
}
@@ -145,13 +145,15 @@ impl NormalModuleFactory {
145145
Ok(None)
146146
}
147147

148-
fn get_loader_resolver(&self, loader_resolve_options: Option<Resolve>) -> Arc<Resolver> {
149-
self.resolver_factory.get(ResolveOptionsWithDependencyType {
150-
resolve_options: loader_resolve_options,
151-
resolve_to_context: false,
152-
dependency_type: DependencyType::CjsRequire,
153-
dependency_category: DependencyCategory::CommonJS,
154-
})
148+
fn get_loader_resolver(&self) -> Arc<Resolver> {
149+
self
150+
.loader_resolver_factory
151+
.get(ResolveOptionsWithDependencyType {
152+
resolve_options: None,
153+
resolve_to_context: false,
154+
dependency_type: DependencyType::CjsRequire,
155+
dependency_category: DependencyCategory::CommonJS,
156+
})
155157
}
156158

157159
pub async fn factorize_normal_module(
@@ -172,7 +174,7 @@ impl NormalModuleFactory {
172174
let context_scheme = get_scheme(data.context.as_ref());
173175
let context = data.context.as_path();
174176
let plugin_driver = &self.plugin_driver;
175-
let loader_resolver = self.get_loader_resolver(data.resolve_options.clone());
177+
let loader_resolver = self.get_loader_resolver();
176178

177179
let mut match_resource_data: Option<ResourceData> = None;
178180
let mut inline_loaders: Vec<ModuleRuleUseLoader> = vec![];
@@ -476,32 +478,94 @@ impl NormalModuleFactory {
476478
pre_loaders.len() + post_loaders.len() + normal_loaders.len() + inline_loaders.len(),
477479
);
478480

479-
all_loaders.extend(post_loaders);
481+
for l in post_loaders {
482+
all_loaders.push(
483+
resolve_each(
484+
plugin_driver,
485+
&self.context.options,
486+
self.context.options.context.as_ref(),
487+
&loader_resolver,
488+
&l.loader,
489+
l.options.as_deref(),
490+
)
491+
.await?,
492+
)
493+
}
494+
495+
let mut resolved_inline_loaders = vec![];
496+
let mut resolved_normal_loaders = vec![];
497+
498+
for l in inline_loaders {
499+
resolved_inline_loaders.push(
500+
resolve_each(
501+
plugin_driver,
502+
&self.context.options,
503+
context,
504+
&loader_resolver,
505+
&l.loader,
506+
l.options.as_deref(),
507+
)
508+
.await?,
509+
)
510+
}
511+
512+
for l in normal_loaders {
513+
resolved_normal_loaders.push(
514+
resolve_each(
515+
plugin_driver,
516+
&self.context.options,
517+
self.context.options.context.as_ref(),
518+
&loader_resolver,
519+
&l.loader,
520+
l.options.as_deref(),
521+
)
522+
.await?,
523+
)
524+
}
525+
480526
if match_resource_data.is_some() {
481-
all_loaders.extend(normal_loaders);
482-
all_loaders.extend(inline_loaders);
527+
all_loaders.extend(resolved_normal_loaders);
528+
all_loaders.extend(resolved_inline_loaders);
483529
} else {
484-
all_loaders.extend(inline_loaders);
485-
all_loaders.extend(normal_loaders);
530+
all_loaders.extend(resolved_inline_loaders);
531+
all_loaders.extend(resolved_normal_loaders);
532+
}
533+
534+
for l in pre_loaders {
535+
all_loaders.push(
536+
resolve_each(
537+
plugin_driver,
538+
&self.context.options,
539+
self.context.options.context.as_ref(),
540+
&loader_resolver,
541+
&l.loader,
542+
l.options.as_deref(),
543+
)
544+
.await?,
545+
)
486546
}
487-
all_loaders.extend(pre_loaders);
488-
489-
let mut loader = Vec::with_capacity(all_loaders.len());
490-
for l in all_loaders {
491-
loader.push(
492-
plugin_driver
493-
.resolve_loader(
494-
&self.context.options,
495-
context,
496-
&loader_resolver,
497-
&l.loader,
498-
l.options.as_deref(),
499-
)
500-
.await?
501-
.ok_or_else(|| internal_error!("Unable to resolve loader {}", &l.loader))?,
502-
);
547+
548+
async fn resolve_each(
549+
plugin_driver: &SharedPluginDriver,
550+
compiler_options: &CompilerOptions,
551+
context: &Path,
552+
loader_resolver: &Resolver,
553+
loader_request: &str,
554+
loader_options: Option<&str>,
555+
) -> Result<Arc<dyn Loader<CompilerContext>>> {
556+
plugin_driver
557+
.resolve_loader(
558+
compiler_options,
559+
context,
560+
loader_resolver,
561+
loader_request,
562+
loader_options,
563+
)
564+
.await?
565+
.ok_or_else(|| internal_error!("Unable to resolve loader {}", loader_request))
503566
}
504-
loader
567+
568+
all_loaders
505569
};
506570

507571
let request = if !loaders.is_empty() {

crates/rspack_core/src/options/compiler_options.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub struct CompilerOptions {
1313
pub target: Target,
1414
pub mode: Mode,
1515
pub resolve: Resolve,
16+
pub resolve_loader: Resolve,
1617
pub builtins: Builtins,
1718
pub module: ModuleOptions,
1819
pub devtool: Devtool,

crates/rspack_loader_sass/tests/fixtures.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
7575
},
7676
target: rspack_core::Target::new(&vec![String::from("web")]).expect("TODO:"),
7777
resolve: rspack_core::Resolve::default(),
78+
resolve_loader: rspack_core::Resolve::default(),
7879
builtins: Default::default(),
7980
module: Default::default(),
8081
stats: Default::default(),

0 commit comments

Comments
 (0)