diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 3e27a603c..e930a52bb 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -5,6 +5,7 @@ use crate::{ }; use cargo_metadata::{diagnostic::Diagnostic, Message}; use indicatif::{ProgressBar, ProgressStyle}; +use lazy_static::lazy_static; use manganis_cli_support::AssetManifestExt; use serde::Serialize; use std::{ @@ -16,6 +17,10 @@ use std::{ }; use wasm_bindgen_cli_support::Bindgen; +lazy_static! { + static ref PROGRESS_BARS: indicatif::MultiProgress = indicatif::MultiProgress::new(); +} + #[derive(Serialize, Debug, Clone)] pub struct BuildResult { pub warnings: Vec, @@ -25,7 +30,7 @@ pub struct BuildResult { pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result { // [1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?) // [2] Generate the appropriate build folders - // [3] Wasm-bindgen the .wasm fiile, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm + // [3] Wasm-bindgen the .wasm file, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm // [4] Wasm-opt the .wasm file with whatever optimizations need to be done // [5][OPTIONAL] Builds the Tailwind CSS file using the Tailwind standalone binary // [6] Link up the html page to the wasm module @@ -61,8 +66,8 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result Result<()> { fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { let mut warning_messages: Vec = vec![]; - let pb = ProgressBar::new_spinner(); + let mut pb = ProgressBar::new_spinner(); pb.enable_steady_tick(Duration::from_millis(200)); + pb = PROGRESS_BARS.add(pb); pb.set_style( ProgressStyle::with_template("{spinner:.dim.bold} {wide_msg}") .unwrap() @@ -413,14 +420,6 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { ); pb.set_message("💼 Waiting to start build the project..."); - struct StopSpinOnDrop(ProgressBar); - - impl Drop for StopSpinOnDrop { - fn drop(&mut self) { - self.0.finish_and_clear(); - } - } - let stdout = cmd.detached().stream_stdout()?; let reader = std::io::BufReader::new(stdout); @@ -456,7 +455,9 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { std::process::exit(1); } } - _ => (), // Unknown message + _ => { + // Unknown message + } } } Ok(warning_messages) diff --git a/packages/cli/src/cli/build.rs b/packages/cli/src/cli/build.rs index e1e8ac607..00e3deb43 100644 --- a/packages/cli/src/cli/build.rs +++ b/packages/cli/src/cli/build.rs @@ -15,8 +15,11 @@ pub struct Build { } impl Build { - pub fn build(self, bin: Option) -> Result<()> { + pub fn build(self, bin: Option, target_dir: Option<&std::path::Path>) -> Result<()> { let mut crate_config = crate::CrateConfig::new(bin)?; + if let Some(target_dir) = target_dir { + crate_config.target_dir = target_dir.to_path_buf(); + } // change the release state. crate_config.with_release(self.build.release); diff --git a/packages/cli/src/cli/cfg.rs b/packages/cli/src/cli/cfg.rs index b2c2c9c1a..6416084d2 100644 --- a/packages/cli/src/cli/cfg.rs +++ b/packages/cli/src/cli/cfg.rs @@ -112,7 +112,7 @@ pub struct ConfigOptsServe { #[clap(long)] pub profile: Option, - /// Build platform: support Web & Desktop [default: "default_platform"] + /// Build platform: support Web, Desktop, and Fullstack [default: "default_platform"] #[clap(long, value_enum)] pub platform: Option, diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index 7ca1b2c9a..3571ca074 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -61,7 +61,7 @@ async fn main() -> anyhow::Result<()> { .map_err(|e| anyhow!("🚫 Translation of HTML into RSX failed: {}", e)), Build(opts) => opts - .build(Some(bin.clone())) + .build(Some(bin.clone()), None) .map_err(|e| anyhow!("🚫 Building project failed: {}", e)), Clean(opts) => opts diff --git a/packages/cli/src/server/fullstack/mod.rs b/packages/cli/src/server/fullstack/mod.rs index 2ee8f7415..62bc4ea88 100644 --- a/packages/cli/src/server/fullstack/mod.rs +++ b/packages/cli/src/server/fullstack/mod.rs @@ -9,6 +9,16 @@ pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> desktop::startup_with_platform::(config, serve).await } +fn start_web_build_thread( + config: &CrateConfig, + serve: &ConfigOptsServe, +) -> std::thread::JoinHandle> { + let serve = serve.clone(); + let target_directory = config.crate_dir.join(".dioxus").join("web"); + std::fs::create_dir_all(&target_directory).unwrap(); + std::thread::spawn(move || build_web(serve, &target_directory)) +} + struct FullstackPlatform { serve: ConfigOptsServe, desktop: desktop::DesktopPlatform, @@ -20,9 +30,7 @@ impl Platform for FullstackPlatform { where Self: Sized, { - { - build_web(serve.clone())?; - } + let thread_handle = start_web_build_thread(config, serve); let mut desktop_config = config.clone(); let desktop_feature = serve.server_feature.clone(); @@ -35,6 +43,9 @@ impl Platform for FullstackPlatform { }; let config = WebAssetConfigDropGuard::new(); let desktop = desktop::DesktopPlatform::start(&desktop_config, serve)?; + thread_handle + .join() + .map_err(|_| anyhow::anyhow!("Failed to join thread"))??; Ok(Self { desktop, @@ -44,8 +55,8 @@ impl Platform for FullstackPlatform { } fn rebuild(&mut self, crate_config: &CrateConfig) -> Result { - build_web(self.serve.clone())?; - { + let thread_handle = start_web_build_thread(crate_config, &self.serve); + let result = { let mut desktop_config = crate_config.clone(); let desktop_feature = self.serve.server_feature.clone(); let features = &mut desktop_config.features; @@ -57,11 +68,15 @@ impl Platform for FullstackPlatform { }; let _gaurd = FullstackServerEnvGuard::new(self.serve.debug); self.desktop.rebuild(&desktop_config) - } + }; + thread_handle + .join() + .map_err(|_| anyhow::anyhow!("Failed to join thread"))??; + result } } -fn build_web(serve: ConfigOptsServe) -> Result<()> { +fn build_web(serve: ConfigOptsServe, target_directory: &std::path::Path) -> Result<()> { let mut web_config: ConfigOptsBuild = serve.into(); let web_feature = web_config.client_feature.clone(); let features = &mut web_config.features; @@ -74,7 +89,7 @@ fn build_web(serve: ConfigOptsServe) -> Result<()> { web_config.platform = Some(crate::cfg::Platform::Web); let _gaurd = FullstackWebEnvGuard::new(web_config.debug); - crate::cli::build::Build { build: web_config }.build(None) + crate::cli::build::Build { build: web_config }.build(None, Some(target_directory)) } // Debug mode web builds have a very large size by default. If debug mode is not enabled, we strip some of the debug info by default diff --git a/packages/fullstack/examples/axum-auth/.gitignore b/packages/fullstack/examples/axum-auth/.gitignore index b2a16319f..21fff11dd 100644 --- a/packages/fullstack/examples/axum-auth/.gitignore +++ b/packages/fullstack/examples/axum-auth/.gitignore @@ -1,3 +1,4 @@ dist target -static \ No newline at end of file +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/axum-desktop/.gitignore b/packages/fullstack/examples/axum-desktop/.gitignore index 6047329c6..21fff11dd 100644 --- a/packages/fullstack/examples/axum-desktop/.gitignore +++ b/packages/fullstack/examples/axum-desktop/.gitignore @@ -1,2 +1,4 @@ dist -target \ No newline at end of file +target +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/axum-hello-world/.gitignore b/packages/fullstack/examples/axum-hello-world/.gitignore index b2a16319f..21fff11dd 100644 --- a/packages/fullstack/examples/axum-hello-world/.gitignore +++ b/packages/fullstack/examples/axum-hello-world/.gitignore @@ -1,3 +1,4 @@ dist target -static \ No newline at end of file +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/axum-router/.gitignore b/packages/fullstack/examples/axum-router/.gitignore index b2a16319f..21fff11dd 100644 --- a/packages/fullstack/examples/axum-router/.gitignore +++ b/packages/fullstack/examples/axum-router/.gitignore @@ -1,3 +1,4 @@ dist target -static \ No newline at end of file +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/salvo-hello-world/.gitignore b/packages/fullstack/examples/salvo-hello-world/.gitignore index b2a16319f..21fff11dd 100644 --- a/packages/fullstack/examples/salvo-hello-world/.gitignore +++ b/packages/fullstack/examples/salvo-hello-world/.gitignore @@ -1,3 +1,4 @@ dist target -static \ No newline at end of file +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/static-hydrated/.gitignore b/packages/fullstack/examples/static-hydrated/.gitignore index c7f237de8..b98a2a695 100644 --- a/packages/fullstack/examples/static-hydrated/.gitignore +++ b/packages/fullstack/examples/static-hydrated/.gitignore @@ -1,3 +1,4 @@ docs target -static \ No newline at end of file +static +.dioxus \ No newline at end of file diff --git a/packages/fullstack/examples/warp-hello-world/.gitignore b/packages/fullstack/examples/warp-hello-world/.gitignore index b2a16319f..21fff11dd 100644 --- a/packages/fullstack/examples/warp-hello-world/.gitignore +++ b/packages/fullstack/examples/warp-hello-world/.gitignore @@ -1,3 +1,4 @@ dist target -static \ No newline at end of file +static +.dioxus \ No newline at end of file