Skip to content

Commit 9b65a4d

Browse files
committed
feat(rolldown_plugin_vite_html): transform script tag into js import (#6351)
1 parent 5bf4086 commit 9b65a4d

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

crates/rolldown_plugin_vite_html/src/lib.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl Plugin for ViteHtmlPlugin {
3030
HookUsage::Transform | HookUsage::GenerateBundle
3131
}
3232

33-
#[expect(unused_variables, unused_assignments)]
33+
#[expect(unused_variables, unused_assignments, clippy::too_many_lines)]
3434
async fn transform(
3535
&self,
3636
ctx: rolldown_plugin::SharedTransformPluginContext,
@@ -60,6 +60,11 @@ impl Plugin for ViteHtmlPlugin {
6060
render_built_url: self.render_built_url.as_deref(),
6161
};
6262

63+
let mut js = String::new();
64+
let mut inline_module_count = 0;
65+
66+
// TODO: Support module_side_effects for module info
67+
// let mut set_modules = Vec::new();
6368
let mut overwrite_attrs = Vec::new();
6469
let mut s = string_wizard::MagicString::new(args.code);
6570

@@ -70,6 +75,7 @@ impl Plugin for ViteHtmlPlugin {
7075
while let Some(node) = stack.pop() {
7176
match &node.data {
7277
html::sink::NodeData::Element { name, attrs, .. } => {
78+
let mut should_remove = false;
7379
if &**name == "script" {
7480
let mut src = None;
7581
let mut is_async = false;
@@ -99,9 +105,26 @@ impl Plugin for ViteHtmlPlugin {
99105
let is_public_file = src.as_ref().is_some_and(|(s, _)| {
100106
rolldown_plugin_utils::check_public_file(s, &self.public_dir).is_some()
101107
});
102-
if is_public_file && let Some((url, span)) = src {
108+
if is_public_file && let Some((url, span)) = src.as_ref() {
103109
overwrite_attrs.push((&url[1..], span));
104110
}
111+
if is_module {
112+
inline_module_count += 1;
113+
if let Some((url, _)) = src.as_ref()
114+
&& !is_public_file
115+
&& !utils::is_excluded_url(url)
116+
{
117+
// TODO: Support module_side_effects for module info
118+
// set_modules.push(url);
119+
// add `<script type="module" src="..."/>` as an import
120+
js.push_str(&rolldown_utils::concat_string!(
121+
"\nimport ",
122+
rolldown_plugin_utils::to_string_literal(url)
123+
));
124+
should_remove = true;
125+
}
126+
todo!()
127+
}
105128
todo!()
106129
}
107130
}
@@ -115,11 +138,26 @@ impl Plugin for ViteHtmlPlugin {
115138
}
116139
}
117140

141+
// TODO: Support module_side_effects for module info
142+
// for url in set_modules {
143+
// match ctx.resolve(&url, Some(args.id), None).await? {
144+
// Ok(resolved_id) => match ctx.get_module_info(&resolved_id.id) {
145+
// Some(module_info) => module_info.module_side_effects = true,
146+
// None => {
147+
// if !resolved_id.external.is_external() {
148+
// ctx.resolve(specifier, importer, extra_options)
149+
// }
150+
// },
151+
// },
152+
// Err(_) => return Err(anyhow::anyhow!("Failed to resolve {url} from {}", args.id)),
153+
// }
154+
// }
155+
118156
for (url, span) in overwrite_attrs {
119157
let asset_url = env.to_output_file_path(url, "html", true, public_to_relative).await?;
120158
utils::overwrite_check_public_file(
121159
&mut s,
122-
span,
160+
*span,
123161
partial_encode_url_path(&asset_url.to_asset_url_in_css_or_html()).into_owned(),
124162
)?;
125163
}

crates/rolldown_plugin_vite_html/src/utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,19 @@ pub fn overwrite_check_public_file(
3535
s.update(start + wrap_offset, span.end - wrap_offset, value);
3636
Ok(())
3737
}
38+
39+
pub fn is_excluded_url(url: &str) -> bool {
40+
url.starts_with('#')
41+
|| {
42+
let b = url.as_bytes();
43+
if b.starts_with(b"//") {
44+
return true;
45+
}
46+
let mut i = 0;
47+
while i < b.len() && b[i].is_ascii_lowercase() {
48+
i += 1;
49+
}
50+
i > 0 && i + 2 < b.len() && &b[i..i + 3] == b"://"
51+
}
52+
|| url.trim_start().get(..5).is_some_and(|p| p.eq_ignore_ascii_case("data:"))
53+
}

0 commit comments

Comments
 (0)