소스 검색

Merge branch 'master' into router-typesafe

Evan Almloff 1 년 전
부모
커밋
f2c4233ef4

+ 9 - 0
packages/cli/docs/src/cmd/build.md

@@ -13,6 +13,7 @@ OPTIONS:
         --example <EXAMPLE>      [default: ""]
         --platform <PLATFORM>    [default: "default_platform"]
         --release                [default: false]
+        --bin                    [default: None]
 ```
 
 You can use this command to build a project:
@@ -37,6 +38,14 @@ dioxus build --platform desktop
 dioxus build --platform web
 ```
 
+## Specify workspace bin
+
+You can add the `--bin` option to select which crate you want Dioxus to build:
+
+```
+dioxus build --bin app
+```
+
 ## Build Example
 
 You can use the `example` option to select a example to build:

+ 10 - 1
packages/cli/docs/src/cmd/clean.md

@@ -7,7 +7,10 @@ dioxus-clean
 Clean build artifacts
 
 USAGE:
-    dioxus clean
+    dioxus clean [OPTIONS]
+
+OPTIONS:
+        --bin   [default: None]
 ```
 
 # Example
@@ -16,3 +19,9 @@ USAGE:
 dioxus clean
 ```
 
+# Specify workspace bin
+You can add the `--bin` option to select which crate you want Dioxus to clean artifacts from:
+
+```
+dioxus clean --bin app
+```

+ 10 - 1
packages/cli/docs/src/cmd/serve.md

@@ -13,7 +13,8 @@ OPTIONS:
         --example <EXAMPLE>      [default: ""]
         --platform <PLATFORM>    [default: "default_platform"]
         --release                [default: false]
-        --hot-reload             [default: false]ß
+        --hot-reload             [default: false]
+        --bin                    [default: None]
 ```
 
 You can use this command to build project and start a dev server:
@@ -31,6 +32,14 @@ You can use the `example` option to serve a example:
 dioxus serve --exmaple test
 ```
 
+## Specify workspace bin
+
+You can add the `--bin` option to select which crate you want Dioxus to build and serve:
+
+```
+dioxus serve --bin app
+```
+
 ## Open Browser
 
 You can add the `--open` option to open system default browser when server startup:

+ 1 - 1
packages/cli/src/cli/autoformat/mod.rs → packages/cli/src/cli/autoformat.rs

@@ -78,7 +78,7 @@ impl Autoformat {
 ///
 /// Doesn't do mod-descending, so it will still try to format unreachable files. TODO.
 async fn autoformat_project(check: bool) -> Result<()> {
-    let crate_config = crate::CrateConfig::new()?;
+    let crate_config = crate::CrateConfig::new(None)?;
 
     let mut files_to_format = vec![];
     collect_rs_files(&crate_config.crate_dir, &mut files_to_format);

+ 2 - 2
packages/cli/src/cli/build/mod.rs → packages/cli/src/cli/build.rs

@@ -12,8 +12,8 @@ pub struct Build {
 }
 
 impl Build {
-    pub fn build(self) -> Result<()> {
-        let mut crate_config = crate::CrateConfig::new()?;
+    pub fn build(self, bin: Option<PathBuf>) -> Result<()> {
+        let mut crate_config = crate::CrateConfig::new(bin)?;
 
         // change the release state.
         crate_config.with_release(self.build.release);

+ 2 - 2
packages/cli/src/cli/clean/mod.rs → packages/cli/src/cli/clean.rs

@@ -6,8 +6,8 @@ use super::*;
 pub struct Clean {}
 
 impl Clean {
-    pub fn clean(self) -> Result<()> {
-        let crate_config = crate::CrateConfig::new()?;
+    pub fn clean(self, bin: Option<PathBuf>) -> Result<()> {
+        let crate_config = crate::CrateConfig::new(bin)?;
 
         let output = Command::new("cargo")
             .arg("clean")

+ 3 - 3
packages/cli/src/cli/config/mod.rs → packages/cli/src/cli/config.rs

@@ -41,19 +41,19 @@ impl Config {
                     return Ok(());
                 }
                 let mut file = File::create(conf_path)?;
-                let content = String::from(include_str!("../../assets/dioxus.toml"))
+                let content = String::from(include_str!("../assets/dioxus.toml"))
                     .replace("{{project-name}}", &name)
                     .replace("{{default-platform}}", &platform);
                 file.write_all(content.as_bytes())?;
                 log::info!("🚩 Init config file completed.");
             }
             Config::FormatPrint {} => {
-                println!("{:#?}", crate::CrateConfig::new()?.dioxus_config);
+                println!("{:#?}", crate::CrateConfig::new(None)?.dioxus_config);
             }
             Config::CustomHtml {} => {
                 let html_path = crate_root.join("index.html");
                 let mut file = File::create(html_path)?;
-                let content = include_str!("../../assets/index.html");
+                let content = include_str!("../assets/index.html");
                 file.write_all(content.as_bytes())?;
                 log::info!("🚩 Create custom html file done.");
             }

+ 0 - 0
packages/cli/src/cli/create/mod.rs → packages/cli/src/cli/create.rs


+ 4 - 0
packages/cli/src/cli/mod.rs

@@ -36,6 +36,10 @@ pub struct Cli {
     /// Enable verbose logging.
     #[clap(short)]
     pub v: bool,
+
+    /// Specify bin target
+    #[clap(global = true, long)]
+    pub bin: Option<String>,
 }
 
 #[derive(Parser)]

+ 0 - 0
packages/cli/src/cli/plugin/mod.rs → packages/cli/src/cli/plugin.rs


+ 2 - 2
packages/cli/src/cli/serve/mod.rs → packages/cli/src/cli/serve.rs

@@ -15,8 +15,8 @@ pub struct Serve {
 }
 
 impl Serve {
-    pub async fn serve(self) -> Result<()> {
-        let mut crate_config = crate::CrateConfig::new()?;
+    pub async fn serve(self, bin: Option<PathBuf>) -> Result<()> {
+        let mut crate_config = crate::CrateConfig::new(bin)?;
 
         // change the relase state.
         crate_config.with_hot_reload(self.serve.hot_reload);

+ 0 - 0
packages/cli/src/cli/tool/mod.rs → packages/cli/src/cli/tool.rs


+ 1 - 1
packages/cli/src/cli/translate/mod.rs → packages/cli/src/cli/translate.rs

@@ -130,7 +130,7 @@ fn determine_input(file: Option<String>, raw: Option<String>) -> Result<String>
 
 #[test]
 fn generates_svgs() {
-    let st = include_str!("../../../tests/svg.html");
+    let st = include_str!("../../tests/svg.html");
 
     let out = convert_html_to_formatted_rsx(&html_parser::Dom::parse(st).unwrap(), true);
 

+ 28 - 12
packages/cli/src/config.rs

@@ -20,9 +20,18 @@ fn default_plugin() -> toml::Value {
 }
 
 impl DioxusConfig {
-    pub fn load() -> crate::error::Result<Option<DioxusConfig>> {
-        let Ok(crate_dir) = crate::cargo::crate_root() else {
-            return Ok(None);
+    pub fn load(bin: Option<PathBuf>) -> crate::error::Result<Option<DioxusConfig>> {
+        let crate_dir = crate::cargo::crate_root();
+
+        let crate_dir = match crate_dir {
+            Ok(dir) => {
+                if let Some(bin) = bin {
+                    dir.join(bin)
+                } else {
+                    dir
+                }
+            }
+            Err(_) => return Ok(None),
         };
         let crate_dir = crate_dir.as_path();
 
@@ -190,14 +199,19 @@ pub enum ExecutableType {
 }
 
 impl CrateConfig {
-    pub fn new() -> Result<Self> {
-        let dioxus_config = DioxusConfig::load()?.unwrap_or_default();
+    pub fn new(bin: Option<PathBuf>) -> Result<Self> {
+        let dioxus_config = DioxusConfig::load(bin.clone())?.unwrap_or_default();
+
+        let crate_root = crate::cargo::crate_root()?;
 
         let crate_dir = if let Some(package) = &dioxus_config.application.sub_package {
-            crate::cargo::crate_root()?.join(package)
+            crate_root.join(package)
+        } else if let Some(bin) = bin {
+            crate_root.join(bin)
         } else {
-            crate::cargo::crate_root()?
+            crate_root
         };
+
         let meta = crate::cargo::Metadata::get()?;
         let workspace_dir = meta.workspace_root;
         let target_dir = meta.target_directory;
@@ -216,8 +230,9 @@ impl CrateConfig {
 
         let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap();
 
-        let output_filename = {
-            match &manifest.package.as_ref().unwrap().default_run {
+        let mut output_filename = String::from("dioxus_app");
+        if let Some(package) = &manifest.package.as_ref() {
+            output_filename = match &package.default_run {
                 Some(default_run_target) => default_run_target.to_owned(),
                 None => manifest
                     .bin
@@ -230,9 +245,10 @@ impl CrateConfig {
                     .or(manifest.bin.first())
                     .or(manifest.lib.as_ref())
                     .and_then(|prod| prod.name.clone())
-                    .expect("No executable or library found from cargo metadata."),
-            }
-        };
+                    .unwrap_or(String::from("dioxus_app")),
+            };
+        }
+
         let executable = ExecutableType::Binary(output_filename);
 
         let release = false;

+ 46 - 4
packages/cli/src/main.rs

@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
 use anyhow::anyhow;
 use clap::Parser;
 use dioxus_cli::*;
@@ -7,13 +9,53 @@ use dioxus_cli::plugin::PluginManager;
 
 use Commands::*;
 
+fn get_bin(bin: Option<String>) -> Result<Option<PathBuf>> {
+    const ERR_MESSAGE: &str = "The `--bin` flag has to be ran in a Cargo workspace.";
+
+    if let Some(ref bin) = bin {
+        let manifest = cargo_toml::Manifest::from_path("./Cargo.toml")
+            .map_err(|_| Error::CargoError(ERR_MESSAGE.to_string()))?;
+
+        if let Some(workspace) = manifest.workspace {
+            for item in workspace.members.iter() {
+                let path = PathBuf::from(item);
+
+                if !path.exists() {
+                    continue;
+                }
+
+                if !path.is_dir() {
+                    continue;
+                }
+
+                if path.ends_with(bin.clone()) {
+                    return Ok(Some(path));
+                }
+            }
+        } else {
+            return Err(Error::CargoError(ERR_MESSAGE.to_string()));
+        }
+    }
+
+    // If the bin exists but we couldn't find it
+    if bin.is_some() {
+        return Err(Error::CargoError(
+            "The specified bin does not exist.".to_string(),
+        ));
+    }
+
+    Ok(None)
+}
+
 #[tokio::main]
 async fn main() -> anyhow::Result<()> {
     let args = Cli::parse();
 
     set_up_logging();
 
-    let _dioxus_config = DioxusConfig::load()
+    let bin = get_bin(args.bin)?;
+
+    let _dioxus_config = DioxusConfig::load(bin.clone())
         .map_err(|e| anyhow!("Failed to load Dioxus config because: {e}"))?
         .unwrap_or_else(|| {
             log::warn!("You appear to be creating a Dioxus project from scratch; we will use the default config");
@@ -30,15 +72,15 @@ async fn main() -> anyhow::Result<()> {
             .map_err(|e| anyhow!("🚫 Translation of HTML into RSX failed: {}", e)),
 
         Build(opts) => opts
-            .build()
+            .build(bin.clone())
             .map_err(|e| anyhow!("🚫 Building project failed: {}", e)),
 
         Clean(opts) => opts
-            .clean()
+            .clean(bin.clone())
             .map_err(|e| anyhow!("🚫 Cleaning project failed: {}", e)),
 
         Serve(opts) => opts
-            .serve()
+            .serve(bin.clone())
             .await
             .map_err(|e| anyhow!("🚫 Serving project failed: {}", e)),
 

+ 12 - 0
packages/web/src/rehydrate.rs

@@ -115,6 +115,12 @@ impl WebsysDom {
         node: &TemplateNode,
         last_node_was_static_text: &mut bool,
     ) -> Result<(), RehydrationError> {
+        log::trace!("rehydrate template node: {:?}", node);
+        if let Ok(current_child) = current_child {
+            if log::log_enabled!(log::Level::Trace) {
+                web_sys::console::log_1(&current_child.clone().into());
+            }
+        }
         match node {
             TemplateNode::Element {
                 children, attrs, ..
@@ -198,6 +204,12 @@ impl WebsysDom {
         dynamic: &DynamicNode,
         last_node_was_static_text: &mut bool,
     ) -> Result<(), RehydrationError> {
+        log::trace!("rehydrate dynamic node: {:?}", dynamic);
+        if let Ok(current_child) = current_child {
+            if log::log_enabled!(log::Level::Trace) {
+                web_sys::console::log_1(&current_child.clone().into());
+            }
+        }
         match dynamic {
             dioxus_core::DynamicNode::Text(VText { id, .. }) => {
                 // skip comment separator before node