From 0d3e2c55422212ffb41ce0de00caac0d5daececd Mon Sep 17 00:00:00 2001 From: William Date: Sat, 27 Mar 2021 22:51:09 +0000 Subject: [PATCH] Fix extremely slow dev builds caused by embedding + compressing assets at compile time (#1395) --- core/tauri-codegen/src/context.rs | 5 +++ core/tauri-codegen/src/embedded_assets.rs | 9 ++++ tauri/src/app/utils.rs | 52 +++++++++++++++++------ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index aed62b7d3..811189b4f 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -24,6 +24,7 @@ pub fn context_codegen(data: ContextData) -> Result Result)>); impl EmbeddedAssets { + #[cfg(not(debug_assertions))] /// Compress a directory of assets, ready to be generated into a [`tauri_api::assets::Assets`]. pub fn new(path: &Path) -> Result { WalkDir::new(&path) @@ -73,6 +74,14 @@ impl EmbeddedAssets { .map(Self) } + #[cfg(debug_assertions)] + /// A dummy EmbeddedAssets for use during development builds. + /// Compressing + including the bytes of assets during development takes a long time. + /// On development builds, assets will simply be resolved & fetched from the configured dist folder. + pub fn new(_: &Path) -> Result { + Ok(EmbeddedAssets(HashMap::new())) + } + /// Use highest compression level for release, the fastest one for everything else fn compression_level() -> i32 { match var("PROFILE").as_ref().map(String::as_str) { diff --git a/tauri/src/app/utils.rs b/tauri/src/app/utils.rs index 605e2b8fa..300db29b3 100644 --- a/tauri/src/app/utils.rs +++ b/tauri/src/app/utils.rs @@ -196,8 +196,11 @@ pub(super) fn build_webview( } } }); - let assets = context.assets; let bundle_identifier = context.config.tauri.bundle.identifier.clone(); + #[cfg(debug_assertions)] + let dist_dir = std::path::PathBuf::from(context.config.build.dist_dir.clone()); + #[cfg(not(debug_assertions))] + let assets = context.assets; let custom_protocol = CustomProtocol { name: "tauri".into(), handler: Box::new(move |path| { @@ -215,17 +218,42 @@ pub(super) fn build_webview( path.chars().skip(1).collect::() }; - let asset_response = assets - .get(&path) - .ok_or(crate::Error::AssetNotFound(path)) - .map(Cow::into_owned); - match asset_response { - Ok(asset) => Ok(asset), - Err(e) => { - #[cfg(debug_assertions)] - eprintln!("{:?}", e); // TODO log::error! - Err(e) - } + // In development builds, resolve, read and directly serve assets in the configured dist folder. + #[cfg(debug_assertions)] + { + dist_dir + .canonicalize() + .or_else(|_| Err(crate::Error::AssetNotFound(path.clone()))) + .and_then(|pathbuf| { + pathbuf + .join(path.clone()) + .canonicalize() + .or_else(|_| Err(crate::Error::AssetNotFound(path.clone()))) + .and_then(|pathbuf| { + + if pathbuf.is_file() && pathbuf.starts_with(&dist_dir) { + match std::fs::read(pathbuf) { + Ok(asset) => return Ok(asset), + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("Error reading asset from dist: {:?}", e); // TODO log::error! + } + } + } + + Err(crate::Error::AssetNotFound(path)) + + }) + }) + } + + // In release builds, fetch + serve decompressed embedded assets. + #[cfg(not(debug_assertions))] + { + assets + .get(&path) + .ok_or(crate::Error::AssetNotFound(path)) + .map(Cow::into_owned) } }), };