Skip to content

Commit 6f534ff

Browse files
authored
feat: transform url in new URL without runtime (#11765)
1 parent b5fc80f commit 6f534ff

File tree

25 files changed

+395
-74
lines changed

25 files changed

+395
-74
lines changed

crates/node_binding/napi-binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ export declare enum BuiltinPluginName {
589589
RstestPlugin = 'RstestPlugin',
590590
RslibPlugin = 'RslibPlugin',
591591
CircularDependencyRspackPlugin = 'CircularDependencyRspackPlugin',
592+
URLPlugin = 'URLPlugin',
592593
JsLoaderRspackPlugin = 'JsLoaderRspackPlugin',
593594
LazyCompilationPlugin = 'LazyCompilationPlugin',
594595
ModuleInfoHeaderPlugin = 'ModuleInfoHeaderPlugin',

crates/rspack_binding_api/src/raw_options/raw_builtins/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use rspack_plugin_ignore::IgnorePlugin;
6464
use rspack_plugin_javascript::{
6565
FlagDependencyExportsPlugin, FlagDependencyUsagePlugin, InferAsyncModulesPlugin, JsPlugin,
6666
MangleExportsPlugin, ModuleConcatenationPlugin, SideEffectsFlagPlugin, api_plugin::APIPlugin,
67-
define_plugin::DefinePlugin, provide_plugin::ProvidePlugin,
67+
define_plugin::DefinePlugin, provide_plugin::ProvidePlugin, url_plugin::URLPlugin,
6868
};
6969
use rspack_plugin_json::JsonPlugin;
7070
use rspack_plugin_library::enable_library_plugin;
@@ -221,6 +221,7 @@ pub enum BuiltinPluginName {
221221
RstestPlugin,
222222
RslibPlugin,
223223
CircularDependencyRspackPlugin,
224+
URLPlugin,
224225

225226
// rspack js adapter plugins
226227
// naming format follow XxxRspackPlugin
@@ -301,6 +302,9 @@ impl<'a> BuiltinPlugin<'a> {
301302
.boxed();
302303
plugins.push(plugin);
303304
}
305+
BuiltinPluginName::URLPlugin => {
306+
plugins.push(URLPlugin::default().boxed());
307+
}
304308
BuiltinPluginName::BannerPlugin => {
305309
let plugin = BannerPlugin::new(
306310
downcast_into::<RawBannerPluginOptions>(self.options)

crates/rspack_core/src/artifacts/code_generation_results.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ impl CodeGenerationDataUrl {
3737
#[derive(Clone, Debug)]
3838
pub struct CodeGenerationPublicPathAutoReplace(pub bool);
3939

40+
#[derive(Clone, Debug)]
41+
pub struct URLStaticMode;
42+
4043
#[derive(Clone, Debug)]
4144
pub struct CodeGenerationDataFilename {
4245
filename: String,

crates/rspack_core/src/concatenated_module.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ use crate::{
4949
ModuleGraphCacheArtifact, ModuleGraphConnection, ModuleIdentifier, ModuleLayer,
5050
ModuleStaticCacheArtifact, ModuleType, NAMESPACE_OBJECT_EXPORT, ParserOptions,
5151
PrefetchExportsInfoMode, Resolve, RuntimeCondition, RuntimeGlobals, RuntimeSpec, SourceType,
52-
UsageState, UsedName, UsedNameItem, define_es_module_flag_statement, escape_identifier,
53-
filter_runtime, get_runtime_key, impl_source_map_config, merge_runtime_condition,
54-
merge_runtime_condition_non_false, module_update_hash, property_access, property_name,
55-
reserved_names::RESERVED_NAMES, returning_function, runtime_condition_expression,
52+
URLStaticMode, UsageState, UsedName, UsedNameItem, define_es_module_flag_statement,
53+
escape_identifier, filter_runtime, get_runtime_key, impl_source_map_config,
54+
merge_runtime_condition, merge_runtime_condition_non_false, module_update_hash, property_access,
55+
property_name, reserved_names::RESERVED_NAMES, returning_function, runtime_condition_expression,
5656
subtract_runtime_condition, to_identifier_with_escaped, to_normal_comment,
5757
};
5858

@@ -203,7 +203,8 @@ pub struct ConcatenatedModuleInfo {
203203
pub all_used_names: HashSet<Atom>,
204204
pub binding_to_ref: HashMap<(Atom, SyntaxContext), Vec<ConcatenatedModuleIdent>>,
205205

206-
pub public_path_auto_replace: Option<bool>,
206+
pub public_path_auto_replacement: Option<bool>,
207+
pub static_url_replacement: bool,
207208
}
208209

209210
#[derive(Debug, Clone)]
@@ -705,6 +706,7 @@ impl Module for ConcatenatedModule {
705706

706707
let mut top_level_declarations: HashSet<Atom> = HashSet::default();
707708
let mut public_path_auto_replace: bool = false;
709+
let mut static_url_replace: bool = false;
708710

709711
for (module_info_id, _raw_condition) in modules_with_info.iter() {
710712
let Some(ModuleInfo::Concatenated(info)) = module_to_info_map.get_mut(module_info_id) else {
@@ -937,9 +939,13 @@ impl Module for ConcatenatedModule {
937939
}
938940

939941
// Handle publicPathAutoReplace for perf
940-
if let Some(info_auto) = info.public_path_auto_replace {
942+
if let Some(info_auto) = info.public_path_auto_replacement {
941943
public_path_auto_replace = public_path_auto_replace || info_auto;
942944
}
945+
946+
if info.static_url_replacement {
947+
static_url_replace = true;
948+
}
943949
}
944950

945951
// Handle external type
@@ -1512,6 +1518,10 @@ impl Module for ConcatenatedModule {
15121518
.insert(CodeGenerationPublicPathAutoReplace(true));
15131519
}
15141520

1521+
if static_url_replace {
1522+
code_generation_result.data.insert(URLStaticMode);
1523+
}
1524+
15151525
code_generation_result
15161526
.data
15171527
.insert(CodeGenerationDataTopLevelDeclarations::new(
@@ -2089,7 +2099,10 @@ impl ConcatenatedModule {
20892099
.data
20902100
.get::<CodeGenerationPublicPathAutoReplace>(
20912101
) {
2092-
module_info.public_path_auto_replace = Some(true);
2102+
module_info.public_path_auto_replacement = Some(true);
2103+
}
2104+
if codegen_res.data.contains::<URLStaticMode>() {
2105+
module_info.static_url_replacement = true;
20932106
}
20942107
Ok(ModuleInfo::Concatenated(Box::new(module_info)))
20952108
} else {

crates/rspack_core/src/dependency/dependency_id.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ impl DependencyId {
1111
let id = fetch_new_dependency_id();
1212
Self(id)
1313
}
14+
15+
pub fn as_u32(&self) -> u32 {
16+
self.0
17+
}
1418
}
1519

1620
impl Default for DependencyId {

crates/rspack_core/src/options/module.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl fmt::Display for DynamicImportFetchPriority {
146146
pub enum JavascriptParserUrl {
147147
Enable,
148148
Disable,
149+
NewUrlRelative,
149150
Relative,
150151
}
151152

@@ -154,6 +155,7 @@ impl From<&str> for JavascriptParserUrl {
154155
match value {
155156
"false" => Self::Disable,
156157
"relative" => Self::Relative,
158+
"new-url-relative" => Self::NewUrlRelative,
157159
_ => Self::Enable,
158160
}
159161
}

crates/rspack_plugin_javascript/src/dependency/url/mod.rs

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
use std::sync::LazyLock;
2+
3+
use regex::Regex;
14
use rspack_cacheable::{cacheable, cacheable_dyn, with::AsPreset};
25
use rspack_core::{
3-
AsContextDependency, ConnectionState, Dependency, DependencyCategory, DependencyCodeGeneration,
4-
DependencyCondition, DependencyConditionFn, DependencyId, DependencyRange, DependencyTemplate,
5-
DependencyTemplateType, DependencyType, FactorizeInfo, ModuleDependency, ModuleGraph,
6-
ModuleGraphCacheArtifact, ModuleGraphConnection, RuntimeGlobals, RuntimeSpec, TemplateContext,
7-
TemplateReplaceSource, UsedByExports, module_id,
6+
AsContextDependency, CodeGenerationPublicPathAutoReplace, ConnectionState, Dependency,
7+
DependencyCategory, DependencyCodeGeneration, DependencyCondition, DependencyConditionFn,
8+
DependencyId, DependencyRange, DependencyTemplate, DependencyTemplateType, DependencyType,
9+
FactorizeInfo, JavascriptParserUrl, ModuleDependency, ModuleGraph, ModuleGraphCacheArtifact,
10+
ModuleGraphConnection, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource,
11+
URLStaticMode, UsedByExports, module_id,
812
};
913
use swc_core::ecma::atoms::Atom;
1014

11-
use crate::connection_active_used_by_exports;
15+
use crate::{connection_active_used_by_exports, runtime::AUTO_PUBLIC_PATH_PLACEHOLDER};
1216

1317
#[cacheable]
1418
#[derive(Debug, Clone)]
@@ -19,7 +23,7 @@ pub struct URLDependency {
1923
range: DependencyRange,
2024
range_url: DependencyRange,
2125
used_by_exports: Option<UsedByExports>,
22-
relative: bool,
26+
mode: Option<JavascriptParserUrl>,
2327
factorize_info: FactorizeInfo,
2428
}
2529

@@ -28,15 +32,15 @@ impl URLDependency {
2832
request: Atom,
2933
range: DependencyRange,
3034
range_url: DependencyRange,
31-
relative: bool,
35+
mode: Option<JavascriptParserUrl>,
3236
) -> Self {
3337
Self {
3438
id: DependencyId::new(),
3539
request,
3640
range,
3741
range_url,
3842
used_by_exports: None,
39-
relative,
43+
mode,
4044
factorize_info: Default::default(),
4145
}
4246
}
@@ -105,6 +109,11 @@ impl AsContextDependency for URLDependency {}
105109
#[derive(Debug, Clone, Default)]
106110
pub struct URLDependencyTemplate;
107111

112+
pub static URL_STATIC_PLACEHOLDER: &str = "RSPACK_AUTO_URL_STATIC_PLACEHOLDER_";
113+
pub static URL_STATIC_PLACEHOLDER_RE: LazyLock<Regex> = LazyLock::new(|| {
114+
Regex::new(&format!(r#"{}(?<dep>\d+)"#, URL_STATIC_PLACEHOLDER)).expect("should be valid regex")
115+
});
116+
108117
impl URLDependencyTemplate {
109118
pub fn template_type() -> DependencyTemplateType {
110119
DependencyTemplateType::Dependency(DependencyType::NewUrl)
@@ -130,34 +139,57 @@ impl DependencyTemplate for URLDependencyTemplate {
130139

131140
runtime_requirements.insert(RuntimeGlobals::REQUIRE);
132141

133-
if dep.relative {
134-
runtime_requirements.insert(RuntimeGlobals::RELATIVE_URL);
135-
source.replace(
136-
dep.range.start,
137-
dep.range.end,
138-
format!(
139-
"/* asset import */ new {}({}({}))",
140-
RuntimeGlobals::RELATIVE_URL,
141-
RuntimeGlobals::REQUIRE,
142-
module_id(compilation, &dep.id, &dep.request, false),
143-
)
144-
.as_str(),
145-
None,
146-
);
147-
} else {
148-
runtime_requirements.insert(RuntimeGlobals::BASE_URI);
149-
source.replace(
150-
dep.range_url.start,
151-
dep.range_url.end,
152-
format!(
153-
"/* asset import */{}({}), {}",
154-
RuntimeGlobals::REQUIRE,
155-
module_id(compilation, &dep.id, &dep.request, false),
156-
RuntimeGlobals::BASE_URI
157-
)
158-
.as_str(),
159-
None,
160-
);
142+
match dep.mode {
143+
Some(JavascriptParserUrl::Relative) => {
144+
runtime_requirements.insert(RuntimeGlobals::RELATIVE_URL);
145+
source.replace(
146+
dep.range.start,
147+
dep.range.end,
148+
format!(
149+
"/* asset import */ new {}({}({}))",
150+
RuntimeGlobals::RELATIVE_URL,
151+
RuntimeGlobals::REQUIRE,
152+
module_id(compilation, &dep.id, &dep.request, false),
153+
)
154+
.as_str(),
155+
None,
156+
);
157+
}
158+
Some(JavascriptParserUrl::NewUrlRelative) => {
159+
code_generatable_context.data.insert(URLStaticMode);
160+
code_generatable_context
161+
.data
162+
.insert(CodeGenerationPublicPathAutoReplace(true));
163+
source.replace(
164+
dep.range.start,
165+
dep.range.end,
166+
format!(
167+
"new URL({}, import.meta.url)",
168+
serde_json::to_string(&format!(
169+
"{AUTO_PUBLIC_PATH_PLACEHOLDER}{URL_STATIC_PLACEHOLDER}{}",
170+
&dep.id.as_u32()
171+
))
172+
.expect("should serde"),
173+
)
174+
.as_str(),
175+
None,
176+
);
177+
}
178+
_ => {
179+
runtime_requirements.insert(RuntimeGlobals::BASE_URI);
180+
source.replace(
181+
dep.range_url.start,
182+
dep.range_url.end,
183+
format!(
184+
"/* asset import */{}({}), {}",
185+
RuntimeGlobals::REQUIRE,
186+
module_id(compilation, &dep.id, &dep.request, false),
187+
RuntimeGlobals::BASE_URI
188+
)
189+
.as_str(),
190+
None,
191+
);
192+
}
161193
}
162194
}
163195
}

crates/rspack_plugin_javascript/src/parser_plugin/url_plugin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rspack_core::{ConstDependency, RuntimeGlobals};
1+
use rspack_core::{ConstDependency, JavascriptParserUrl, RuntimeGlobals};
22
use rspack_util::SpanExt;
33
use swc_core::{
44
common::Spanned,
@@ -45,7 +45,7 @@ pub fn get_url_request(
4545
}
4646

4747
pub struct URLPlugin {
48-
pub relative: bool,
48+
pub mode: Option<JavascriptParserUrl>,
4949
}
5050

5151
impl JavascriptParserPlugin for URLPlugin {
@@ -96,7 +96,7 @@ impl JavascriptParserPlugin for URLPlugin {
9696
request.into(),
9797
expr.span.into(),
9898
(start, end).into(),
99-
self.relative,
99+
self.mode,
100100
);
101101
let dep_idx = parser.next_dependency_idx();
102102
parser.add_dependency(Box::new(dep));

crates/rspack_plugin_javascript/src/plugin/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod infer_async_modules_plugin;
1616
mod mangle_exports_plugin;
1717
pub mod module_concatenation_plugin;
1818
mod side_effects_flag_plugin;
19+
pub mod url_plugin;
1920

2021
pub use drive::*;
2122
pub use flag_dependency_exports_plugin::*;

0 commit comments

Comments
 (0)