diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs index 034d8fbb73..e69eae010f 100644 --- a/packages/cli/src/cli/bundle.rs +++ b/packages/cli/src/cli/bundle.rs @@ -1,6 +1,6 @@ use core::panic; use dioxus_cli_config::ExecutableType; -use std::{fs::create_dir_all, str::FromStr}; +use std::{env::current_dir, fs::create_dir_all, str::FromStr}; use tauri_bundler::{BundleSettings, PackageSettings, SettingsBuilder}; @@ -153,10 +153,31 @@ impl Bundle { let static_asset_output_dir = static_asset_output_dir.display().to_string(); println!("Adding assets from {} to bundle", static_asset_output_dir); - if let Some(resources) = &mut bundle_settings.resources { - resources.push(static_asset_output_dir); - } else { - bundle_settings.resources = Some(vec![static_asset_output_dir]); + + // Don't copy the executable or the old bundle directory + let ignored_files = [ + crate_config.out_dir().join("bundle"), + crate_config.out_dir().join(name), + ]; + + for entry in std::fs::read_dir(&static_asset_output_dir)?.flatten() { + let path = entry.path().canonicalize()?; + if ignored_files.iter().any(|f| path.starts_with(f)) { + continue; + } + + // Tauri bundle will add a __root__ prefix if the input path is absolute even though the output path is relative? + // We strip the prefix here to make sure the input path is relative so that the bundler puts the output path in the right place + let path = path + .strip_prefix(¤t_dir()?) + .unwrap() + .display() + .to_string(); + if let Some(resources) = &mut bundle_settings.resources_map { + resources.insert(path, "".to_string()); + } else { + bundle_settings.resources_map = Some([(path, "".to_string())].into()); + } } let mut settings = SettingsBuilder::new() diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs index 93b97a2bec..862c935528 100644 --- a/packages/desktop/src/protocol.rs +++ b/packages/desktop/src/protocol.rs @@ -2,7 +2,7 @@ use crate::{assets::*, edits::EditQueue}; use dioxus_interpreter_js::eval::NATIVE_EVAL_JS; use dioxus_interpreter_js::unified_bindings::SLEDGEHAMMER_JS; use dioxus_interpreter_js::NATIVE_JS; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use wry::{ http::{status::StatusCode, Request, Response}, RequestAsyncResponder, Result, @@ -82,14 +82,8 @@ fn assets_head() -> Option { target_os = "openbsd" ))] { - let root = crate::protocol::get_asset_root_or_default(); - let assets_head_path = "__assets_head.html"; - let mut head = root.join(assets_head_path); - // If we can't find it, add the dist directory and try again - // When bundling we currently copy the whole dist directory to the output directory instead of the individual files because of a limitation of cargo bundle2 - if !head.exists() { - head = root.join("dist").join(assets_head_path); - } + let assets_head_path = PathBuf::from("__assets_head.html"); + let head = resolve_resource(&assets_head_path); match std::fs::read_to_string(&head) { Ok(s) => Some(s), Err(err) => { @@ -112,6 +106,27 @@ fn assets_head() -> Option { } } +fn resolve_resource(path: &Path) -> PathBuf { + let mut base_path = get_asset_root_or_default(); + if running_in_dev_mode() { + base_path.push(path); + } else { + let mut resource_path = PathBuf::new(); + for component in path.components() { + // Tauri-bundle inserts special path segments for abnormal component paths + match component { + Component::Prefix(_) => {} + Component::RootDir => resource_path.push("_root_"), + Component::CurDir => {} + Component::ParentDir => resource_path.push("_up_"), + Component::Normal(p) => resource_path.push(p), + } + } + base_path.push(resource_path); + } + base_path +} + /// Handle a request from the webview /// /// - Tries to stream edits if they're requested. @@ -157,19 +172,13 @@ pub(super) fn desktop_handler( fn serve_from_fs(path: PathBuf) -> Result>> { // If the path is relative, we'll try to serve it from the assets directory. - let mut asset = get_asset_root_or_default().join(&path); + let mut asset = resolve_resource(&path); // If we can't find it, make it absolute and try again if !asset.exists() { asset = PathBuf::from("/").join(&path); } - // If we can't find it, add the dist directory and try again - // When bundling we currently copy the whole dist directory to the output directory instead of the individual files because of a limitation of cargo bundle2 - if !asset.exists() { - asset = get_asset_root_or_default().join("dist").join(&path); - } - if !asset.exists() { return Ok(Response::builder() .status(StatusCode::NOT_FOUND) @@ -226,6 +235,12 @@ fn get_asset_root_or_default() -> PathBuf { get_asset_root().unwrap_or_else(|| std::env::current_dir().unwrap()) } +fn running_in_dev_mode() -> bool { + // If running under cargo, there's no bundle! + // There might be a smarter/more resilient way of doing this + std::env::var_os("CARGO").is_some() +} + /// Get the asset directory, following tauri/cargo-bundles directory discovery approach /// /// Currently supports: @@ -237,9 +252,7 @@ fn get_asset_root_or_default() -> PathBuf { /// - [ ] Android #[allow(unreachable_code)] fn get_asset_root() -> Option { - // If running under cargo, there's no bundle! - // There might be a smarter/more resilient way of doing this - if std::env::var_os("CARGO").is_some() { + if running_in_dev_mode() { return dioxus_cli_config::CURRENT_CONFIG .as_ref() .map(|c| c.out_dir())