Fix extremely slow dev builds caused by embedding + compressing assets at compile time (#1395)

This commit is contained in:
William
2021-03-27 22:51:09 +00:00
committed by GitHub
parent 9aa64454be
commit 0d3e2c5542
3 changed files with 54 additions and 12 deletions

View File

@@ -24,6 +24,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
let assets = EmbeddedAssets::new(&dist_dir)?;
// handle default window icons for Windows targets
#[cfg(not(debug_assertions))]
let default_window_icon = if cfg!(windows) {
let icon_path = config_parent.join("icons/icon.ico").display().to_string();
quote!(Some(include_bytes!(#icon_path)))
@@ -31,6 +32,10 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
quote!(None)
};
// in development builds, don't use an icon as it slows down cargo check
#[cfg(debug_assertions)]
let default_window_icon = quote!(None);
// double braces are purposeful to force the code into a block expression
Ok(quote! {{
use ::tauri::api::private::{OnceCell, AsTauriContext};

View File

@@ -51,6 +51,7 @@ pub enum EmbeddedAssetsError {
pub struct EmbeddedAssets(HashMap<AssetKey, (String, Vec<u8>)>);
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<Self, EmbeddedAssetsError> {
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<Self, EmbeddedAssetsError> {
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) {

View File

@@ -196,8 +196,11 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
}
}
});
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<A: ApplicationExt + 'static>(
path.chars().skip(1).collect::<String>()
};
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)
}
}),
};