Add hash files support to 0.7 (#2894)

* Add support for JS and WASM file name hashing

* Add `<HashedStylesheet />`

* Update `<HashedStylesheet />`

* Whoops

* Fix formatting

* My IDE is just refusing to work apparently

* I hate my IDE

* Don't run the doctest

* Just remove the example, I don't know enough about doctest for this
This commit is contained in:
mrvillage 2024-08-30 17:29:59 -04:00 committed by GitHub
parent ceff827a77
commit 4f1ee65e6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 10 deletions

View file

@ -39,12 +39,36 @@ pub fn HydrationScripts(
options: LeptosOptions,
#[prop(optional)] islands: bool,
) -> impl IntoView {
let pkg_path = &options.site_pkg_dir;
let output_name = &options.output_name;
let mut wasm_output_name = output_name.clone();
if std::option_env!("LEPTOS_OUTPUT_NAME").is_none() {
wasm_output_name.push_str("_bg");
let mut js_file_name = options.output_name.to_string();
let mut wasm_file_name = options.output_name.to_string();
if options.hash_files {
let hash_path = std::env::current_exe()
.map(|path| {
path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
})
.unwrap_or_default()
.join(&options.hash_file);
if hash_path.exists() {
let hashes = std::fs::read_to_string(&hash_path)
.expect("failed to read hash file");
for line in hashes.lines() {
let line = line.trim();
if !line.is_empty() {
if let Some((file, hash)) = line.split_once(':') {
if file == "js" {
js_file_name.push_str(&format!(".{}", hash));
} else if file == "wasm" {
wasm_file_name.push_str(&format!(".{}", hash));
}
}
}
}
}
} else if std::option_env!("LEPTOS_OUTPUT_NAME").is_none() {
wasm_file_name.push_str("_bg");
}
let pkg_path = &options.site_pkg_dir;
#[cfg(feature = "nonce")]
let nonce = crate::nonce::use_nonce();
#[cfg(not(feature = "nonce"))]
@ -59,16 +83,16 @@ pub fn HydrationScripts(
};
view! {
<link rel="modulepreload" href=format!("/{pkg_path}/{output_name}.js") nonce=nonce.clone()/>
<link rel="modulepreload" href=format!("/{pkg_path}/{js_file_name}.js") nonce=nonce.clone()/>
<link
rel="preload"
href=format!("/{pkg_path}/{wasm_output_name}.wasm")
href=format!("/{pkg_path}/{wasm_file_name}.wasm")
r#as="fetch"
r#type="application/wasm"
crossorigin=nonce.clone().unwrap_or_default()
/>
<script type="module" nonce=nonce>
{format!("{script}({pkg_path:?}, {output_name:?}, {wasm_output_name:?})")}
{format!("{script}({pkg_path:?}, {js_file_name:?}, {wasm_file_name:?})")}
</script>
}
}

View file

@ -1,7 +1,7 @@
use crate::register;
use leptos::{
attr::global::GlobalAttributes, component, tachys::html::element::link,
IntoView,
attr::global::GlobalAttributes, component, prelude::LeptosOptions,
tachys::html::element::link, IntoView,
};
/// Injects an [`HTMLLinkElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement) into the document
@ -34,3 +34,46 @@ pub fn Stylesheet(
// TODO additional attributes
register(link().id(id).rel("stylesheet").href(href))
}
/// Injects an [`HTMLLinkElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement) into the document head that loads a `cargo-leptos`-hashed stylesheet.
#[component]
pub fn HashedStylesheet(
/// Leptos options
options: LeptosOptions,
/// An ID for the stylesheet.
#[prop(optional, into)]
id: Option<String>,
) -> impl IntoView {
let mut css_file_name = options.output_name.to_string();
if options.hash_files {
let hash_path = std::env::current_exe()
.map(|path| {
path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
})
.unwrap_or_default()
.join(&options.hash_file);
if hash_path.exists() {
let hashes = std::fs::read_to_string(&hash_path)
.expect("failed to read hash file");
for line in hashes.lines() {
let line = line.trim();
if !line.is_empty() {
if let Some((file, hash)) = line.split_once(':') {
if file == "css" {
css_file_name.push_str(&format!(".{}", hash));
}
}
}
}
}
}
css_file_name.push_str(".css");
let pkg_path = &options.site_pkg_dir;
// TODO additional attributes
register(
link()
.id(id)
.rel("stylesheet")
.href(format!("/{pkg_path}/{css_file_name}")),
)
}