Hashless assets (#4312)

* add support for external assets

* fix playwright tests

* add more documentation to with_hash_suffix

* restore external asset hashing tests

* Update gtk workflow dependencies

* fix doc test

* multiple versions of libgtk

* clear dx in playwright tests

* fix fullstack caching test

* try without apt cache

* cache everything except libxdo-dev

* revert ci changes

* fix wasm asset options

* fix merge conflict

* recommend the used attribute instead

* Move options to AssetOptionsBuilder

* Don't deprecate non-canonical new asset options functions

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2025-06-30 19:21:49 -07:00
1 parent 0bd376b873
commit e74c838441
22 files changed
+569 -316

No files matched your search

+29 -19
View File
@@ -1,6 +1,6 @@
use anyhow::Context;
use manganis::{CssModuleAssetOptions, FolderAssetOptions};
use manganis_core::{AssetOptions, CssAssetOptions, ImageAssetOptions, JsAssetOptions};
use manganis::{AssetOptions, CssModuleAssetOptions, FolderAssetOptions};
use manganis_core::{AssetVariant, CssAssetOptions, ImageAssetOptions, JsAssetOptions};
use std::path::Path;
use crate::css::{process_css_module, process_scss};
@@ -26,10 +26,10 @@ pub(crate) fn process_file_to_with_options(
output_path: &Path,
in_folder: bool,
) -> anyhow::Result<()> {
// If the file already exists, then we must have a file with the same hash
// already. The hash has the file contents and options, so if we find a file
// with the same hash, we probably already created this file in the past
if output_path.exists() {
// If the file already exists and this is a hashed asset, then we must have a file
// with the same hash already. The hash has the file contents and options, so if we
// find a file with the same hash, we probably already created this file in the past
if output_path.exists() && options.hash_suffix() {
return Ok(());
}
if let Some(parent) = output_path.parent() {
@@ -48,7 +48,7 @@ pub(crate) fn process_file_to_with_options(
.unwrap_or_default()
.to_string_lossy()
));
let resolved_options = resolve_asset_options(source, options);
let resolved_options = resolve_asset_options(source, options.variant());
match &resolved_options {
ResolvedAssetType::Css(options) => {
@@ -86,6 +86,16 @@ pub(crate) fn process_file_to_with_options(
}
}
// Remove the existing output file if it exists
if output_path.exists() {
if output_path.is_file() {
std::fs::remove_file(output_path).context("Failed to remove previous output file")?;
} else if output_path.is_dir() {
std::fs::remove_dir_all(output_path)
.context("Failed to remove previous output file")?;
}
}
// If everything was successful, rename the temp file to the final output path
std::fs::rename(temp_path, output_path).context("Failed to rename output file")?;
@@ -111,14 +121,14 @@ pub(crate) enum ResolvedAssetType {
File,
}
pub(crate) fn resolve_asset_options(source: &Path, options: &AssetOptions) -> ResolvedAssetType {
pub(crate) fn resolve_asset_options(source: &Path, options: &AssetVariant) -> ResolvedAssetType {
match options {
AssetOptions::Image(image) => ResolvedAssetType::Image(*image),
AssetOptions::Css(css) => ResolvedAssetType::Css(*css),
AssetOptions::CssModule(css) => ResolvedAssetType::CssModule(*css),
AssetOptions::Js(js) => ResolvedAssetType::Js(*js),
AssetOptions::Folder(folder) => ResolvedAssetType::Folder(*folder),
AssetOptions::Unknown => resolve_unknown_asset_options(source),
AssetVariant::Image(image) => ResolvedAssetType::Image(*image),
AssetVariant::Css(css) => ResolvedAssetType::Css(*css),
AssetVariant::CssModule(css) => ResolvedAssetType::CssModule(*css),
AssetVariant::Js(js) => ResolvedAssetType::Js(*js),
AssetVariant::Folder(folder) => ResolvedAssetType::Folder(*folder),
AssetVariant::Unknown => resolve_unknown_asset_options(source),
_ => {
tracing::warn!("Unknown asset options... you may need to update the Dioxus CLI. Defaulting to a generic file: {:?}", options);
resolve_unknown_asset_options(source)
@@ -128,14 +138,14 @@ pub(crate) fn resolve_asset_options(source: &Path, options: &AssetOptions) -> Re
fn resolve_unknown_asset_options(source: &Path) -> ResolvedAssetType {
match source.extension().map(|e| e.to_string_lossy()).as_deref() {
Some("scss" | "sass") => ResolvedAssetType::Scss(CssAssetOptions::new()),
Some("css") => ResolvedAssetType::Css(CssAssetOptions::new()),
Some("js") => ResolvedAssetType::Js(JsAssetOptions::new()),
Some("scss" | "sass") => ResolvedAssetType::Scss(CssAssetOptions::default()),
Some("css") => ResolvedAssetType::Css(CssAssetOptions::default()),
Some("js") => ResolvedAssetType::Js(JsAssetOptions::default()),
Some("json") => ResolvedAssetType::Json,
Some("jpg" | "jpeg" | "png" | "webp" | "avif") => {
ResolvedAssetType::Image(ImageAssetOptions::new())
ResolvedAssetType::Image(ImageAssetOptions::default())
}
_ if source.is_dir() => ResolvedAssetType::Folder(FolderAssetOptions::new()),
_ if source.is_dir() => ResolvedAssetType::Folder(FolderAssetOptions::default()),
_ => ResolvedAssetType::File,
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ pub fn process_folder(source: &Path, output_folder: &Path) -> anyhow::Result<()>
/// Optimize a file without changing any of its contents significantly (e.g. by changing the extension)
fn process_file_minimal(input_path: &Path, output_path: &Path) -> anyhow::Result<()> {
process_file_to_with_options(
&manganis_core::AssetOptions::Unknown,
&manganis_core::AssetOptions::builder().into_asset_options(),
input_path,
output_path,
true,
+6 -3
View File
@@ -62,7 +62,7 @@ pub(crate) fn hash_file_with_options(
hasher: &mut impl Hasher,
in_folder: bool,
) -> anyhow::Result<()> {
let resolved_options = resolve_asset_options(source, options);
let resolved_options = resolve_asset_options(source, options.variant());
match &resolved_options {
// Scss and JS can import files during the bundling process. We need to hash
@@ -145,8 +145,11 @@ pub fn add_hash_to_asset(asset: &mut BundledAsset) {
.map(|byte| format!("{byte:x}"))
.collect::<String>();
let file_stem = source_path.file_stem().unwrap_or(file_name);
let mut bundled_path =
PathBuf::from(format!("{}-dxh{hash}", file_stem.to_string_lossy()));
let mut bundled_path = if asset.options().hash_suffix() {
PathBuf::from(format!("{}-dxh{hash}", file_stem.to_string_lossy()))
} else {
PathBuf::from(file_stem)
};
if let Some(ext) = ext {
bundled_path.set_extension(ext);