浏览代码

FIx:

- asset hotreloading for desktop,
- asset dir for dxserve on desktop,
- extend features with platform
Jonathan Kelley 1 年之前
父节点
当前提交
bb8b4dc2fb

+ 33 - 0
packages/cli-config/src/config.rs

@@ -7,12 +7,17 @@ use std::path::PathBuf;
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
 #[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
 pub enum Platform {
+    /// Targeting the web platform using WASM
     #[cfg_attr(feature = "cli", clap(name = "web"))]
     #[serde(rename = "web")]
     Web,
+
+    /// Targeting the desktop platform using Tao/Wry-based webview
     #[cfg_attr(feature = "cli", clap(name = "desktop"))]
     #[serde(rename = "desktop")]
     Desktop,
+
+    /// Targeting the server platform using Axum and Dioxus-Fullstack
     #[cfg_attr(feature = "cli", clap(name = "fullstack"))]
     #[serde(rename = "fullstack")]
     Fullstack,
@@ -536,6 +541,34 @@ impl CrateConfig {
         self.cargo_args = cargo_args;
         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 {

+ 1 - 1
packages/cli/Cargo.toml

@@ -10,7 +10,7 @@ keywords = ["react", "gui", "cli", "dioxus", "wasm"]
 
 [dependencies]
 # cli core
-clap = { version = "4.2", features = ["derive"] }
+clap = { version = "4.2", features = ["derive", "cargo"] }
 thiserror = { workspace = true }
 wasm-bindgen-cli-support = "0.2"
 colored = "2.0.0"

+ 18 - 10
packages/cli/src/builder.rs

@@ -15,6 +15,7 @@ use std::{
     io::Read,
     panic,
     path::PathBuf,
+    process::Command,
     time::Duration,
 };
 use wasm_bindgen_cli_support::Bindgen;
@@ -98,16 +99,17 @@ pub fn build_web(
     // [1] Build the .wasm module
     log::info!("🚅 Running build command...");
 
-    let wasm_check_command = std::process::Command::new("rustup")
-        .args(["show"])
-        .output()?;
-
-    let wasm_check_output = String::from_utf8(wasm_check_command.stdout).unwrap();
-    if !wasm_check_output.contains("wasm32-unknown-unknown") {
-        log::info!("wasm32-unknown-unknown target not detected, installing..");
-        let _ = std::process::Command::new("rustup")
-            .args(["target", "add", "wasm32-unknown-unknown"])
-            .output()?;
+    // If the user has rustup, we can check if the wasm32-unknown-unknown target is installed
+    // Otherwise we can just assume it is installed - which i snot great...
+    // 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();
+        if !wasm_check_output.contains("wasm32-unknown-unknown") {
+            log::info!("wasm32-unknown-unknown target not detected, installing..");
+            let _ = Command::new("rustup")
+                .args(["target", "add", "wasm32-unknown-unknown"])
+                .output()?;
+        }
     }
 
     let cmd = subprocess::Exec::cmd("cargo")
@@ -333,6 +335,12 @@ pub fn build_desktop(
     let _manganis_support = ManganisSupportGuard::default();
     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")
         .set_rust_flags(rust_flags)
         .env("CARGO_TARGET_DIR", &config.target_dir)

+ 1 - 0
packages/cli/src/cli/build.rs

@@ -50,6 +50,7 @@ impl Build {
         }
 
         crate_config.set_cargo_args(self.build.cargo_args.clone());
+        crate_config.extend_with_platform(platform);
 
         // #[cfg(feature = "plugin")]
         // let _ = crate::plugin::PluginManager::on_build_start(&crate_config, &platform);

+ 3 - 0
packages/cli/src/cli/bundle.rs

@@ -82,6 +82,9 @@ impl Bundle {
         }
 
         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
         // Since the `bundle()` function is only run for the desktop platform,

+ 1 - 1
packages/cli/src/cli/cfg.rs

@@ -178,7 +178,7 @@ pub struct ConfigOptsBundle {
 
     /// Build platform: support Web & Desktop [default: "default_platform"]
     #[clap(long)]
-    pub platform: Option<String>,
+    pub platform: Option<Platform>,
 
     /// Space separated list of features to activate
     #[clap(long)]

+ 1 - 0
packages/cli/src/cli/serve.rs

@@ -60,6 +60,7 @@ impl Serve {
         }
 
         let platform = platform.unwrap_or(crate_config.dioxus_config.application.default_platform);
+        crate_config.extend_with_platform(platform);
 
         // start the develop server
         use server::{desktop, fullstack, web};

+ 0 - 2
packages/cli/src/lib.rs

@@ -2,8 +2,6 @@
 #![doc(html_logo_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;
 pub mod builder;
 pub mod server;

+ 26 - 16
packages/cli/src/server/output.rs

@@ -46,7 +46,7 @@ pub fn print_console_info(
     let custom_html_file = if crate_root.join("index.html").is_file() {
         "Custom [index.html]"
     } else {
-        "Default"
+        "None"
     };
     let url_rewrite = if config.dioxus_config.web.watcher.index_on_404 {
         "True"
@@ -58,9 +58,9 @@ pub fn print_console_info(
 
     if options.changed.is_empty() {
         println!(
-            "{} @ v{} [{}] \n",
+            "{} @ v{} [{}]",
             "Dioxus".bold().green(),
-            crate::DIOXUS_CLI_VERSION,
+            clap::crate_version!(),
             chrono::Local::now().format("%H:%M:%S").to_string().dimmed()
         );
     } else {
@@ -79,40 +79,50 @@ pub fn print_console_info(
     if let Some(WebServerInfo { ip, port }) = web_info {
         if config.dioxus_config.web.https.enabled == Some(true) {
             println!(
-                "\t> Local : {}",
+                "    > Local address: {}",
                 format!("https://localhost:{}/", port).blue()
             );
             println!(
-                "\t> Network : {}",
+                "    > Network address: {}",
                 format!("https://{}:{}/", ip, port).blue()
             );
-            println!("\t> HTTPS : {}", "Enabled".to_string().green());
+            println!("    > HTTPS: {}", "Enabled".to_string().green());
         } else {
             println!(
-                "\t> Local : {}",
+                "    > Local address: {}",
                 format!("http://localhost:{}/", port).blue()
             );
             println!(
-                "\t> Network : {}",
+                "    > Network address: {}",
                 format!("http://{}:{}/", ip, port).blue()
             );
-            println!("\t> HTTPS : {}", "Disabled".to_string().red());
+            println!("    > HTTPS status: {}", "Disabled".to_string().red());
         }
     }
     println!();
-    println!("\t> Profile : {}", profile.green());
-    println!("\t> Hot Reload : {}", hot_reload.cyan());
+
+    println!("    > Hot Reload Mode: {}", hot_reload.cyan());
     if !proxies.is_empty() {
-        println!("\t> Proxies :");
+        println!("    > Proxies :");
         for proxy in proxies {
-            println!("\t\t- {}", proxy.backend.blue());
+            println!("    - {}", proxy.backend.blue());
         }
     }
-    println!("\t> Index Template : {}", custom_html_file.green());
-    println!("\t> URL Rewrite [index_on_404] : {}", url_rewrite.purple());
+    println!("    > Custom index.html: {}", custom_html_file.green());
+    println!("    > Serve index.html on 404: {}", url_rewrite.purple());
     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()
     );
     println!();

+ 5 - 2
packages/desktop/src/app.rs

@@ -278,8 +278,11 @@ impl App {
                 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
packages/desktop/src/protocol.rs

@@ -221,7 +221,10 @@ fn get_asset_root() -> Option<PathBuf> {
     // 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() {
-        return None;
+        return dioxus_cli_config::CURRENT_CONFIG
+            .as_ref()
+            .map(|c| c.out_dir())
+            .ok();
     }
 
     #[cfg(target_os = "macos")]

+ 8 - 0
packages/desktop/src/webview.rs

@@ -221,4 +221,12 @@ impl WebviewInstance {
             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());");
+    }
 }