- asset hotreloading for desktop,
- asset dir for dxserve on desktop,
- extend features with platform
This commit is contained in:
Jonathan Kelley committed 2024-03-13 17:15:49 -07:00
1 parent c532d3ec1a
commit bb8b4dc2fb
12 files changed
+101 -33

No files matched your search

+33
View File
@@ -7,12 +7,17 @@ use std::path::PathBuf;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
#[cfg_attr(feature = "cli", derive(clap::ValueEnum))] #[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
pub enum Platform { pub enum Platform {
/// Targeting the web platform using WASM
#[cfg_attr(feature = "cli", clap(name = "web"))] #[cfg_attr(feature = "cli", clap(name = "web"))]
#[serde(rename = "web")] #[serde(rename = "web")]
Web, Web,
/// Targeting the desktop platform using Tao/Wry-based webview
#[cfg_attr(feature = "cli", clap(name = "desktop"))] #[cfg_attr(feature = "cli", clap(name = "desktop"))]
#[serde(rename = "desktop")] #[serde(rename = "desktop")]
Desktop, Desktop,
/// Targeting the server platform using Axum and Dioxus-Fullstack
#[cfg_attr(feature = "cli", clap(name = "fullstack"))] #[cfg_attr(feature = "cli", clap(name = "fullstack"))]
#[serde(rename = "fullstack")] #[serde(rename = "fullstack")]
Fullstack, Fullstack,
@@ -536,6 +541,34 @@ impl CrateConfig {
self.cargo_args = cargo_args; self.cargo_args = cargo_args;
self self
} }
pub fn add_features(&mut self, feature: Vec<String>) -> &mut Self {
if let Some(features) = &mut self.features {
features.extend(feature);
} else {
self.features = Some(feature);
}
self
}
#[cfg(feature = "cli")]
pub fn extend_with_platform(&mut self, platform: Platform) -> &mut Self {
let manifest = &self.manifest;
let features = match platform {
Platform::Web if manifest.features.contains_key("web") => {
vec!["web".to_string()]
}
Platform::Desktop if manifest.features.contains_key("desktop") => {
vec!["desktop".to_string()]
}
_ => {
// fullstack has its own feature insertion - we use a different featureset for the client and server
vec![]
}
};
self.add_features(features);
self
}
} }
fn true_bool() -> bool { fn true_bool() -> bool {
+1 -1
View File
@@ -10,7 +10,7 @@ keywords = ["react", "gui", "cli", "dioxus", "wasm"]
[dependencies] [dependencies]
# cli core # cli core
clap = { version = "4.2", features = ["derive"] } clap = { version = "4.2", features = ["derive", "cargo"] }
thiserror = { workspace = true } thiserror = { workspace = true }
wasm-bindgen-cli-support = "0.2" wasm-bindgen-cli-support = "0.2"
colored = "2.0.0" colored = "2.0.0"
+18 -10
View File
@@ -15,6 +15,7 @@ use std::{
io::Read, io::Read,
panic, panic,
path::PathBuf, path::PathBuf,
process::Command,
time::Duration, time::Duration,
}; };
use wasm_bindgen_cli_support::Bindgen; use wasm_bindgen_cli_support::Bindgen;
@@ -98,16 +99,17 @@ pub fn build_web(
// [1] Build the .wasm module // [1] Build the .wasm module
log::info!("🚅 Running build command..."); log::info!("🚅 Running build command...");
let wasm_check_command = std::process::Command::new("rustup") // If the user has rustup, we can check if the wasm32-unknown-unknown target is installed
.args(["show"]) // Otherwise we can just assume it is installed - which i snot great...
.output()?; // Eventually we can poke at the errors and let the user know they need to install the target
if let Ok(wasm_check_command) = Command::new("rustup").args(["show"]).output() {
let wasm_check_output = String::from_utf8(wasm_check_command.stdout).unwrap(); let wasm_check_output = String::from_utf8(wasm_check_command.stdout).unwrap();
if !wasm_check_output.contains("wasm32-unknown-unknown") { if !wasm_check_output.contains("wasm32-unknown-unknown") {
log::info!("wasm32-unknown-unknown target not detected, installing.."); log::info!("wasm32-unknown-unknown target not detected, installing..");
let _ = std::process::Command::new("rustup") let _ = Command::new("rustup")
.args(["target", "add", "wasm32-unknown-unknown"]) .args(["target", "add", "wasm32-unknown-unknown"])
.output()?; .output()?;
}
} }
let cmd = subprocess::Exec::cmd("cargo") let cmd = subprocess::Exec::cmd("cargo")
@@ -333,6 +335,12 @@ pub fn build_desktop(
let _manganis_support = ManganisSupportGuard::default(); let _manganis_support = ManganisSupportGuard::default();
let _guard = AssetConfigDropGuard::new(); let _guard = AssetConfigDropGuard::new();
// set the asset dir via cli args
env::set_var(
"DIOXUS_ASSET_DIR",
config.asset_dir().canonicalize().unwrap(),
);
let mut cmd = subprocess::Exec::cmd("cargo") let mut cmd = subprocess::Exec::cmd("cargo")
.set_rust_flags(rust_flags) .set_rust_flags(rust_flags)
.env("CARGO_TARGET_DIR", &config.target_dir) .env("CARGO_TARGET_DIR", &config.target_dir)
+1
View File
@@ -50,6 +50,7 @@ impl Build {
} }
crate_config.set_cargo_args(self.build.cargo_args.clone()); crate_config.set_cargo_args(self.build.cargo_args.clone());
crate_config.extend_with_platform(platform);
// #[cfg(feature = "plugin")] // #[cfg(feature = "plugin")]
// let _ = crate::plugin::PluginManager::on_build_start(&crate_config, &platform); // let _ = crate::plugin::PluginManager::on_build_start(&crate_config, &platform);
+3
View File
@@ -82,6 +82,9 @@ impl Bundle {
} }
crate_config.set_cargo_args(self.build.cargo_args); crate_config.set_cargo_args(self.build.cargo_args);
if let Some(platform) = self.build.platform {
crate_config.extend_with_platform(platform);
}
// build the desktop app // build the desktop app
// Since the `bundle()` function is only run for the desktop platform, // Since the `bundle()` function is only run for the desktop platform,
+1 -1
View File
@@ -178,7 +178,7 @@ pub struct ConfigOptsBundle {
/// Build platform: support Web & Desktop [default: "default_platform"] /// Build platform: support Web & Desktop [default: "default_platform"]
#[clap(long)] #[clap(long)]
pub platform: Option<String>, pub platform: Option<Platform>,
/// Space separated list of features to activate /// Space separated list of features to activate
#[clap(long)] #[clap(long)]
+1
View File
@@ -60,6 +60,7 @@ impl Serve {
} }
let platform = platform.unwrap_or(crate_config.dioxus_config.application.default_platform); let platform = platform.unwrap_or(crate_config.dioxus_config.application.default_platform);
crate_config.extend_with_platform(platform);
// start the develop server // start the develop server
use server::{desktop, fullstack, web}; use server::{desktop, fullstack, web};
-2
View File
@@ -2,8 +2,6 @@
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
pub const DIOXUS_CLI_VERSION: &str = "0.4.1";
mod assets; mod assets;
pub mod builder; pub mod builder;
pub mod server; pub mod server;
+26 -16
View File
@@ -46,7 +46,7 @@ pub fn print_console_info(
let custom_html_file = if crate_root.join("index.html").is_file() { let custom_html_file = if crate_root.join("index.html").is_file() {
"Custom [index.html]" "Custom [index.html]"
} else { } else {
"Default" "None"
}; };
let url_rewrite = if config.dioxus_config.web.watcher.index_on_404 { let url_rewrite = if config.dioxus_config.web.watcher.index_on_404 {
"True" "True"
@@ -58,9 +58,9 @@ pub fn print_console_info(
if options.changed.is_empty() { if options.changed.is_empty() {
println!( println!(
"{} @ v{} [{}] \n", "{} @ v{} [{}]",
"Dioxus".bold().green(), "Dioxus".bold().green(),
crate::DIOXUS_CLI_VERSION, clap::crate_version!(),
chrono::Local::now().format("%H:%M:%S").to_string().dimmed() chrono::Local::now().format("%H:%M:%S").to_string().dimmed()
); );
} else { } else {
@@ -79,40 +79,50 @@ pub fn print_console_info(
if let Some(WebServerInfo { ip, port }) = web_info { if let Some(WebServerInfo { ip, port }) = web_info {
if config.dioxus_config.web.https.enabled == Some(true) { if config.dioxus_config.web.https.enabled == Some(true) {
println!( println!(
"\t> Local : {}", " > Local address: {}",
format!("https://localhost:{}/", port).blue() format!("https://localhost:{}/", port).blue()
); );
println!( println!(
"\t> Network : {}", " > Network address: {}",
format!("https://{}:{}/", ip, port).blue() format!("https://{}:{}/", ip, port).blue()
); );
println!("\t> HTTPS : {}", "Enabled".to_string().green()); println!(" > HTTPS: {}", "Enabled".to_string().green());
} else { } else {
println!( println!(
"\t> Local : {}", " > Local address: {}",
format!("http://localhost:{}/", port).blue() format!("http://localhost:{}/", port).blue()
); );
println!( println!(
"\t> Network : {}", " > Network address: {}",
format!("http://{}:{}/", ip, port).blue() format!("http://{}:{}/", ip, port).blue()
); );
println!("\t> HTTPS : {}", "Disabled".to_string().red()); println!(" > HTTPS status: {}", "Disabled".to_string().red());
} }
} }
println!(); println!();
println!("\t> Profile : {}", profile.green());
println!("\t> Hot Reload : {}", hot_reload.cyan()); println!(" > Hot Reload Mode: {}", hot_reload.cyan());
if !proxies.is_empty() { if !proxies.is_empty() {
println!("\t> Proxies :"); println!(" > Proxies :");
for proxy in proxies { for proxy in proxies {
println!("\t\t- {}", proxy.backend.blue()); println!(" - {}", proxy.backend.blue());
} }
} }
println!("\t> Index Template : {}", custom_html_file.green()); println!(" > Custom index.html: {}", custom_html_file.green());
println!("\t> URL Rewrite [index_on_404] : {}", url_rewrite.purple()); println!(" > Serve index.html on 404: {}", url_rewrite.purple());
println!(); println!();
println!( println!(
"\t> Build Time Use : {} millis", " > Build Features: [ {} ]",
config
.features
.clone()
.unwrap_or_default()
.join(", ")
.green()
);
println!(" > Build Profile: {}", profile.green());
println!(
" > Build took: {} millis",
options.elapsed_time.to_string().green().bold() options.elapsed_time.to_string().green().bold()
); );
println!(); println!();
+5 -2
View File
@@ -278,8 +278,11 @@ impl App {
self.control_flow = ControlFlow::Exit; self.control_flow = ControlFlow::Exit;
} }
// todo: enable asset hotreloading in desktop dioxus_hot_reload::HotReloadMsg::UpdateAsset(_) => {
dioxus_hot_reload::HotReloadMsg::UpdateAsset(_) => {} for webview in self.webviews.values_mut() {
webview.kick_stylsheets();
}
}
} }
} }
+4 -1
View File
@@ -221,7 +221,10 @@ fn get_asset_root() -> Option<PathBuf> {
// If running under cargo, there's no bundle! // If running under cargo, there's no bundle!
// There might be a smarter/more resilient way of doing this // There might be a smarter/more resilient way of doing this
if std::env::var_os("CARGO").is_some() { if std::env::var_os("CARGO").is_some() {
return None; return dioxus_cli_config::CURRENT_CONFIG
.as_ref()
.map(|c| c.out_dir())
.ok();
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
+8
View File
@@ -221,4 +221,12 @@ impl WebviewInstance {
self.desktop_context.send_edits(); self.desktop_context.send_edits();
} }
} }
pub fn kick_stylsheets(&self) {
// run eval in the webview to kick the stylesheets by appending a query string
// we should do something less clunky than this
_ = self.desktop_context
.webview
.evaluate_script("document.querySelectorAll('link[rel=\"stylesheet\"]').forEach((el) => el.href = el.href + \"?\" + Math.random());");
}
} }