mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-19 20:28:54 +03:00
* feat(core): fallback to file system for AssetResolver::get, closes #8411 Ports #10356 to v2 * fix test --------- Co-authored-by: Chip Reed <chip@chip.sh>
This commit is contained in:
parent
d03332617c
commit
1e0793b682
6
.changes/asset-resolver-dev-fallback.md
Normal file
6
.changes/asset-resolver-dev-fallback.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri": patch:enhance
|
||||
"tauri-codegen": patch:enhance
|
||||
---
|
||||
|
||||
Enhance `AssetResolver::get` in development mode by reading distDir directly as a fallback to the embedded assets.
|
@ -483,6 +483,15 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
|
||||
quote!(::std::option::Option::None)
|
||||
};
|
||||
|
||||
let maybe_config_parent_setter = if dev {
|
||||
let config_parent = config_parent.to_string_lossy();
|
||||
quote!({
|
||||
context.with_config_parent(#config_parent);
|
||||
})
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
Ok(quote!({
|
||||
#[allow(unused_mut, clippy::let_and_return)]
|
||||
let mut context = #root::Context::new(
|
||||
@ -496,7 +505,10 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
|
||||
#runtime_authority,
|
||||
#plugin_global_api_script
|
||||
);
|
||||
|
||||
#with_tray_icon_code
|
||||
#maybe_config_parent_setter
|
||||
|
||||
context
|
||||
}))
|
||||
}
|
||||
|
@ -269,7 +269,45 @@ pub struct AssetResolver<R: Runtime> {
|
||||
|
||||
impl<R: Runtime> AssetResolver<R> {
|
||||
/// Gets the app asset associated with the given path.
|
||||
///
|
||||
/// Resolves to the embedded asset that is part of the app
|
||||
/// in dev when [`devPath`](https://tauri.app/v1/api/config/#buildconfig.devpath) points to a folder in your filesystem
|
||||
/// or in production when [`distDir`](https://tauri.app/v1/api/config/#buildconfig.distdir)
|
||||
/// points to your frontend assets.
|
||||
///
|
||||
/// Fallbacks to reading the asset from the [distDir] folder so the behavior is consistent in development.
|
||||
/// Note that the dist directory must exist so you might need to build your frontend assets first.
|
||||
pub fn get(&self, path: String) -> Option<Asset> {
|
||||
#[cfg(dev)]
|
||||
{
|
||||
// on dev if the devPath is a path to a directory we have the embedded assets
|
||||
// so we can use get_asset() directly
|
||||
// we only fallback to reading from distDir directly if we're using an external URL (which is likely)
|
||||
if let (Some(_), Some(crate::utils::config::FrontendDist::Directory(dist_path))) = (
|
||||
&self.manager.config().build.dev_url,
|
||||
&self.manager.config().build.frontend_dist,
|
||||
) {
|
||||
let asset_path = std::path::PathBuf::from(&path)
|
||||
.components()
|
||||
.filter(|c| !matches!(c, std::path::Component::RootDir))
|
||||
.collect::<std::path::PathBuf>();
|
||||
|
||||
let asset_path = self
|
||||
.manager
|
||||
.config_parent()
|
||||
.map(|p| p.join(dist_path).join(&asset_path))
|
||||
.unwrap_or_else(|| dist_path.join(&asset_path));
|
||||
return std::fs::read(asset_path).ok().map(|bytes| {
|
||||
let mime_type = crate::utils::mime_type::MimeType::parse(&bytes, &path);
|
||||
Asset {
|
||||
bytes,
|
||||
mime_type,
|
||||
csp_header: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.manager.get_asset(path).ok()
|
||||
}
|
||||
|
||||
|
@ -379,6 +379,8 @@ impl<R: Runtime> Assets<R> for EmbeddedAssets {
|
||||
#[tauri_macros::default_runtime(Wry, wry)]
|
||||
pub struct Context<R: Runtime> {
|
||||
pub(crate) config: Config,
|
||||
#[cfg(dev)]
|
||||
pub(crate) config_parent: Option<std::path::PathBuf>,
|
||||
/// Asset provider.
|
||||
pub assets: Box<dyn Assets<R>>,
|
||||
pub(crate) default_window_icon: Option<image::Image<'static>>,
|
||||
@ -507,6 +509,8 @@ impl<R: Runtime> Context<R> {
|
||||
) -> Self {
|
||||
Self {
|
||||
config,
|
||||
#[cfg(dev)]
|
||||
config_parent: None,
|
||||
assets,
|
||||
default_window_icon,
|
||||
app_icon,
|
||||
@ -519,6 +523,14 @@ impl<R: Runtime> Context<R> {
|
||||
plugin_global_api_scripts,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(dev)]
|
||||
#[doc(hidden)]
|
||||
pub fn with_config_parent(&mut self, config_parent: impl AsRef<std::path::Path>) {
|
||||
self
|
||||
.config_parent
|
||||
.replace(config_parent.as_ref().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: expand these docs
|
||||
|
@ -179,6 +179,8 @@ pub struct AppManager<R: Runtime> {
|
||||
pub listeners: Listeners,
|
||||
pub state: Arc<StateManager>,
|
||||
pub config: Config,
|
||||
#[cfg(dev)]
|
||||
pub config_parent: Option<std::path::PathBuf>,
|
||||
pub assets: Box<dyn Assets<R>>,
|
||||
|
||||
pub app_icon: Option<Vec<u8>>,
|
||||
@ -278,6 +280,8 @@ impl<R: Runtime> AppManager<R> {
|
||||
listeners: Listeners::default(),
|
||||
state: Arc::new(state),
|
||||
config: context.config,
|
||||
#[cfg(dev)]
|
||||
config_parent: context.config_parent,
|
||||
assets: context.assets,
|
||||
app_icon: context.app_icon,
|
||||
package_info: context.package_info,
|
||||
@ -458,6 +462,11 @@ impl<R: Runtime> AppManager<R> {
|
||||
&self.config
|
||||
}
|
||||
|
||||
#[cfg(dev)]
|
||||
pub fn config_parent(&self) -> Option<&std::path::PathBuf> {
|
||||
self.config_parent.as_ref()
|
||||
}
|
||||
|
||||
pub fn package_info(&self) -> &PackageInfo {
|
||||
&self.package_info
|
||||
}
|
||||
|
@ -135,6 +135,9 @@ pub fn mock_context<R: Runtime, A: Assets<R>>(assets: A) -> crate::Context<R> {
|
||||
pattern: Pattern::Brownfield,
|
||||
runtime_authority: RuntimeAuthority::new(Default::default(), Resolved::default()),
|
||||
plugin_global_api_scripts: None,
|
||||
|
||||
#[cfg(dev)]
|
||||
config_parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user