diff --git a/src/assets/index.html b/src/assets/index.html index 12e1e5678..9934e490d 100644 --- a/src/assets/index.html +++ b/src/assets/index.html @@ -10,8 +10,8 @@
{script_include} diff --git a/src/builder.rs b/src/builder.rs index 381ef8b28..0ecde96cd 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -19,7 +19,7 @@ pub fn build(config: &CrateConfig) -> Result<()> { out_dir, crate_dir, target_dir, - static_dir, + public_dir, executable, dioxus_config, .. @@ -56,7 +56,7 @@ pub fn build(config: &CrateConfig) -> Result<()> { } // [2] Establish the output directory structure - let bindgen_outdir = out_dir.join("assets"); + let bindgen_outdir = out_dir.join("assets").join("dioxus"); // [3] Bindgen the final binary for use easy linking let mut bindgen_builder = Bindgen::new(); @@ -87,12 +87,26 @@ pub fn build(config: &CrateConfig) -> Result<()> { .out_name(&dioxus_config.application.name) .generate(&bindgen_outdir)?; - let copy_options = fs_extra::dir::CopyOptions::new(); - if static_dir.is_dir() { - match fs_extra::dir::copy(static_dir, out_dir, ©_options) { - Ok(_) => {} - Err(_e) => { - log::warn!("Error copying dir: {}", _e); + let copy_options = fs_extra::dir::CopyOptions { + overwrite: true, + skip_exist: false, + buffer_size: 64000, + copy_inside: false, + content_only: false, + depth: 0, + }; + if public_dir.is_dir() { + for entry in std::fs::read_dir(&public_dir)? { + let path = entry?.path(); + if path.is_file() { + std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?; + } else { + match fs_extra::dir::copy(&path, out_dir, ©_options) { + Ok(_) => {} + Err(_e) => { + log::warn!("Error copying dir: {}", _e); + } + } } } } diff --git a/src/cli/build/mod.rs b/src/cli/build/mod.rs index fc329a305..e24a99822 100644 --- a/src/cli/build/mod.rs +++ b/src/cli/build/mod.rs @@ -1,4 +1,6 @@ -use crate::cfg::ConfigOptsBuild; +use std::{io::Write, path::PathBuf}; + +use crate::{cfg::ConfigOptsBuild, gen_page}; use structopt::StructOpt; /// Build the Rust WASM app and all of its assets. @@ -18,6 +20,24 @@ impl Build { crate::builder::build(&crate_config)?; + let temp = gen_page(&crate_config.dioxus_config, false); + + let mut file = std::fs::File::create( + crate_config + .crate_dir + .join( + crate_config + .dioxus_config + .web + .app + .out_dir + .clone() + .unwrap_or(PathBuf::from("dist")), + ) + .join("index.html"), + )?; + file.write_all(temp.as_bytes())?; + Ok(()) } } diff --git a/src/cli/clean/mod.rs b/src/cli/clean/mod.rs index 1edcd053a..4ab7653d2 100644 --- a/src/cli/clean/mod.rs +++ b/src/cli/clean/mod.rs @@ -1,6 +1,41 @@ +use std::{ + fs::remove_dir_all, + path::PathBuf, + process::{Command, Stdio}, +}; + use structopt::StructOpt; /// Build the Rust WASM app and all of its assets. #[derive(Clone, Debug, StructOpt)] #[structopt(name = "clean")] pub struct Clean {} + +impl Clean { + pub fn clean(self) -> anyhow::Result<()> { + let crate_config = crate::CrateConfig::new()?; + + let output = Command::new("cargo") + .arg("clean") + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output()?; + + if !output.status.success() { + log::error!("Cargo clean failed."); + return Ok(()); + } + + let out_dir = crate_config + .dioxus_config + .web + .app + .out_dir + .unwrap_or(PathBuf::from("dist")); + if crate_config.crate_dir.join(&out_dir).is_dir() { + remove_dir_all(crate_config.crate_dir.join(&out_dir))?; + } + + Ok(()) + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 93cbfef28..6224cea32 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -37,8 +37,7 @@ pub enum Commands { /// Init a new project for Dioxus. Init(init::Init), // /// Clean output artifacts. - // Clean(clean::Clean), - + Clean(clean::Clean), // /// Trunk config controls. // Config(config::Config), } diff --git a/src/cli/serve/mod.rs b/src/cli/serve/mod.rs index 7d580f7fb..19a7f28ff 100644 --- a/src/cli/serve/mod.rs +++ b/src/cli/serve/mod.rs @@ -1,4 +1,4 @@ -use crate::{cfg::ConfigOptsServe, gen_page, server}; +use crate::{cfg::ConfigOptsServe, gen_page, server, CrateConfig}; use std::{io::Write, path::PathBuf}; use structopt::StructOpt; @@ -18,6 +18,16 @@ impl Serve { crate::builder::build(&crate_config).expect("build failed"); + // generate dev-index page + Serve::regen_dev_page(&crate_config)?; + + // start the develop server + server::startup(crate_config.clone()).await?; + + Ok(()) + } + + pub fn regen_dev_page(crate_config: &CrateConfig) -> anyhow::Result<()> { let serve_html = gen_page(&crate_config.dioxus_config, true); let mut file = std::fs::File::create( @@ -36,11 +46,6 @@ impl Serve { )?; file.write_all(serve_html.as_bytes())?; - // start the develop server - server::startup(crate_config.clone()).await?; - Ok(()) } - - pub fn regen_page() {} } diff --git a/src/config.rs b/src/config.rs index 39a3d2038..403ad0e81 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,9 +13,8 @@ impl DioxusConfig { let crate_dir = crate::cargo::crate_root()?; if !crate_dir.join("Dioxus.toml").is_file() { - return Err(crate::error::Error::CargoError( - "Dioxus.toml not found".into(), - )); + log::warn!("Config file: `Dioxus.toml` not found."); + return Ok(Self::default()); } let mut dioxus_conf_file = File::open(crate_dir.join("Dioxus.toml"))?; @@ -34,6 +33,36 @@ impl DioxusConfig { } } +impl Default for DioxusConfig { + fn default() -> Self { + Self { + application: ApplicationConfig { + name: "dioxus".into(), + platforms: vec![String::from("web")], + }, + web: WebConfig { + app: WebAppConfing { + title: Some("dioxus | ⛺".into()), + out_dir: Some(PathBuf::from("dist")), + public_dir: Some(PathBuf::from("public")), + }, + watcher: WebWatcherConfing { + watch_path: Some(vec![PathBuf::from("src")]), + reload_html: Some(false), + }, + resource: WebResourceConfing { + dev: WebDevResourceConfing { + style: Some(vec![]), + script: Some(vec![]), + }, + style: Some(vec![]), + script: Some(vec![]), + }, + }, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationConfig { pub name: String, @@ -51,12 +80,13 @@ pub struct WebConfig { pub struct WebAppConfing { pub title: Option, pub out_dir: Option, - pub static_dir: Option, + pub public_dir: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WebWatcherConfing { pub watch_path: Option>, + pub reload_html: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -78,7 +108,7 @@ pub struct CrateConfig { pub crate_dir: PathBuf, pub workspace_dir: PathBuf, pub target_dir: PathBuf, - pub static_dir: PathBuf, + pub public_dir: PathBuf, pub manifest: cargo_toml::Manifest, pub executable: ExecutableType, pub dioxus_config: DioxusConfig, @@ -107,9 +137,9 @@ impl CrateConfig { let cargo_def = &crate_dir.join("Cargo.toml"); - let static_dir = match dioxus_config.web.app.static_dir { + let public_dir = match dioxus_config.web.app.public_dir { Some(ref v) => crate_dir.join(v), - None => crate_dir.join("static"), + None => crate_dir.join("public"), }; let manifest = cargo_toml::Manifest::from_path(&cargo_def).unwrap(); @@ -124,7 +154,7 @@ impl CrateConfig { (&manifest) .package .as_ref() - .and_then(|pkg| Some(pkg.name.replace("-", "_"))) + .and_then(|pkg| Some(pkg.name.clone())) .clone() }) .expect("No lib found from cargo metadata"); @@ -137,7 +167,7 @@ impl CrateConfig { crate_dir, workspace_dir, target_dir, - static_dir, + public_dir, manifest, executable, release, diff --git a/src/main.rs b/src/main.rs index 69636c6e3..70f92cf95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,9 +19,11 @@ async fn main() -> Result<()> { } } - // Commands::Clean(_) => { - // // - // } + Commands::Clean(opts) => { + if let Err(e) = opts.clean() { + log::error!("clean error: {}", e); + } + } // Commands::Config(_) => { // // diff --git a/src/server/mod.rs b/src/server/mod.rs index 4d33f524e..3151975d5 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -13,7 +13,7 @@ use std::{ }; use tower_http::services::ServeDir; -use crate::{builder, crate_root, CrateConfig}; +use crate::{builder, serve::Serve, CrateConfig}; struct WsRelodState { update: bool, @@ -71,6 +71,15 @@ pub async fn startup(config: CrateConfig) -> anyhow::Result<()> { if let Ok(_) = builder::build(&watcher_conf) { // change the websocket reload state to true; // the page will auto-reload. + if watcher_conf + .dioxus_config + .web + .watcher + .reload_html + .unwrap_or(false) + { + let _ = Serve::regen_dev_page(&watcher_conf); + } watcher_ws_state.lock().unwrap().change(); } } diff --git a/src/template/config.toml b/src/template/config.toml index ea1efbd4b..44f5baabd 100644 --- a/src/template/config.toml +++ b/src/template/config.toml @@ -15,11 +15,15 @@ title = "dioxus | ⛺" # Web `build` & `serve` dist path out_dir = "dist" -# resource (static) file folder -static_dir = "static" +# resource (public) file folder +public_dir = "public" [web.watcher] +# when watcher trigger, regenerate the `index.html` +reload_html = true + +# which files or dirs will be watcher monitoring watch_path = ["src"] # include `assets` in web platform