feat: add Dioxus.toml
This commit is contained in:
1 parent
70adff7e44
commit
9bb10c65a3
13 files changed
+269
-170
No files matched your search
@@ -0,0 +1,25 @@
|
|||||||
|
(function () {
|
||||||
|
var protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||||
|
|
||||||
|
var url = protocol + "//" + window.location.host + "/_dioxus/ws";
|
||||||
|
|
||||||
|
var poll_interval = 2000;
|
||||||
|
|
||||||
|
var reload_upon_connect = () => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.onopen = () => window.location.reload();
|
||||||
|
ws.onclose = reload_upon_connect;
|
||||||
|
}, poll_interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
|
||||||
|
ws.onmessage = (ev) => {
|
||||||
|
if (ev.data == "reload") {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = reload_upon_connect;
|
||||||
|
})();
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{app_title}</title>
|
||||||
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
{style_include}
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="main"></div>
|
||||||
|
<!-- Note the usage of `type=module` here as this is an ES6 module -->
|
||||||
|
<script type="module">
|
||||||
|
import init from "./assets/{app_name}.js";
|
||||||
|
init("./assets/{app_name}_bg.wasm");
|
||||||
|
</script>
|
||||||
|
{script_include}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+53
-28
@@ -1,11 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{CrateConfig, ExecutableType},
|
config::{CrateConfig, ExecutableType},
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
|
DioxusConfig,
|
||||||
};
|
};
|
||||||
use std::{io::Write, path::PathBuf, process::Command};
|
use std::process::Command;
|
||||||
use wasm_bindgen_cli_support::Bindgen;
|
use wasm_bindgen_cli_support::Bindgen;
|
||||||
|
|
||||||
pub fn build(config: &CrateConfig, dist: PathBuf) -> Result<()> {
|
pub fn build(config: &CrateConfig) -> Result<()> {
|
||||||
/*
|
/*
|
||||||
[1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?)
|
[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
|
[2] Generate the appropriate build folders
|
||||||
@@ -15,15 +16,15 @@ pub fn build(config: &CrateConfig, dist: PathBuf) -> Result<()> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let CrateConfig {
|
let CrateConfig {
|
||||||
|
out_dir,
|
||||||
crate_dir,
|
crate_dir,
|
||||||
target_dir,
|
target_dir,
|
||||||
static_dir,
|
static_dir,
|
||||||
executable,
|
executable,
|
||||||
|
dioxus_config,
|
||||||
..
|
..
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
let out_dir = crate_dir.join(dist);
|
|
||||||
|
|
||||||
let t_start = std::time::Instant::now();
|
let t_start = std::time::Instant::now();
|
||||||
|
|
||||||
// [1] Build the .wasm module
|
// [1] Build the .wasm module
|
||||||
@@ -53,7 +54,7 @@ pub fn build(config: &CrateConfig, dist: PathBuf) -> Result<()> {
|
|||||||
let reason = String::from_utf8_lossy(&output.stderr).to_string();
|
let reason = String::from_utf8_lossy(&output.stderr).to_string();
|
||||||
return Err(Error::BuildFailed(reason));
|
return Err(Error::BuildFailed(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
// [2] Establish the output directory structure
|
// [2] Establish the output directory structure
|
||||||
let bindgen_outdir = out_dir.join("assets");
|
let bindgen_outdir = out_dir.join("assets");
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ pub fn build(config: &CrateConfig, dist: PathBuf) -> Result<()> {
|
|||||||
.keep_debug(true)
|
.keep_debug(true)
|
||||||
.remove_name_section(false)
|
.remove_name_section(false)
|
||||||
.remove_producers_section(false)
|
.remove_producers_section(false)
|
||||||
.out_name("module")
|
.out_name(&dioxus_config.application.name)
|
||||||
.generate(&bindgen_outdir)?;
|
.generate(&bindgen_outdir)?;
|
||||||
|
|
||||||
let copy_options = fs_extra::dir::CopyOptions::new();
|
let copy_options = fs_extra::dir::CopyOptions::new();
|
||||||
@@ -101,28 +102,52 @@ pub fn build(config: &CrateConfig, dist: PathBuf) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_page(module: &str) -> String {
|
pub fn gen_page(config: &DioxusConfig, serve: bool) -> String {
|
||||||
format!(
|
let mut html = String::from(include_str!("./assets/index.html"));
|
||||||
r#"
|
|
||||||
<html>
|
let resouces = config.web.resource.clone();
|
||||||
<head>
|
|
||||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
let mut style_list = resouces.style.unwrap_or(vec![]);
|
||||||
<meta charset="UTF-8" />
|
let mut script_list = resouces.script.unwrap_or(vec![]);
|
||||||
</head>
|
|
||||||
<body>
|
if serve {
|
||||||
<div id="main">
|
let mut dev_style = resouces.dev.style.clone().unwrap_or(vec![]);
|
||||||
</div>
|
let mut dev_script = resouces.dev.script.clone().unwrap_or(vec![]);
|
||||||
<!-- Note the usage of `type=module` here as this is an ES6 module -->
|
style_list.append(&mut dev_style);
|
||||||
<script type="module">
|
script_list.append(&mut dev_script);
|
||||||
import init from "{}";
|
}
|
||||||
init("./assets/module_bg.wasm");
|
|
||||||
</script>
|
let mut style_str = String::new();
|
||||||
<div id="dioxusroot"> </div>
|
for style in style_list {
|
||||||
</body>
|
style_str.push_str(&format!(
|
||||||
</html>
|
"<link rel=\"stylesheet\" href=\"{}\">\n",
|
||||||
"#,
|
&style.to_str().unwrap(),
|
||||||
module
|
))
|
||||||
)
|
}
|
||||||
|
html = html.replace("{style_include}", &style_str);
|
||||||
|
|
||||||
|
let mut script_str = String::new();
|
||||||
|
for script in script_list {
|
||||||
|
script_str.push_str(&format!(
|
||||||
|
"<script src=\"{}\"></script>\n",
|
||||||
|
&script.to_str().unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
html = html.replace("{script_include}", &script_str);
|
||||||
|
|
||||||
|
if serve {
|
||||||
|
html += &format!(
|
||||||
|
"<script>{}</script>",
|
||||||
|
include_str!("./assets/autoreload.js")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
html = html.replace("{app_name}", &config.application.name);
|
||||||
|
|
||||||
|
let title = config.web.app.title.clone().unwrap_or("dioxus | ⛺".into());
|
||||||
|
|
||||||
|
html.replace("{app_title}", &title)
|
||||||
}
|
}
|
||||||
|
|
||||||
// use binary_install::{Cache, Download};
|
// use binary_install::{Cache, Download};
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use crate::cfg::ConfigOptsBuild;
|
use crate::cfg::ConfigOptsBuild;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
@@ -18,10 +16,7 @@ impl Build {
|
|||||||
// change the relase state.
|
// change the relase state.
|
||||||
crate_config.with_release(self.build.release);
|
crate_config.with_release(self.build.release);
|
||||||
|
|
||||||
crate::builder::build(
|
crate::builder::build(&crate_config)?;
|
||||||
&crate_config,
|
|
||||||
self.build.dist.unwrap_or(PathBuf::from("dist")),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,6 @@ pub struct ConfigOptsBuild {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
|
|
||||||
/// The output dir for all final assets [default: dist]
|
|
||||||
#[structopt(short, long, parse(from_os_str))]
|
|
||||||
pub dist: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// The public URL from which assets are to be served [default: /]
|
|
||||||
#[structopt(long, parse(from_str=parse_public_url))]
|
|
||||||
pub public_url: Option<String>,
|
|
||||||
|
|
||||||
/// Optional pattern for the app loader script [default: None]
|
/// Optional pattern for the app loader script [default: None]
|
||||||
///
|
///
|
||||||
/// Patterns should include the sequences `{base}`, `{wasm}`, and `{js}` in order to
|
/// Patterns should include the sequences `{base}`, `{wasm}`, and `{js}` in order to
|
||||||
@@ -74,14 +66,6 @@ pub struct ConfigOptsServe {
|
|||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
|
|
||||||
/// The output dir for all final assets [default: dist]
|
|
||||||
#[structopt(short, long, parse(from_os_str))]
|
|
||||||
pub dist: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// The public URL from which assets are to be served [default: /]
|
|
||||||
#[structopt(long, parse(from_str=parse_public_url))]
|
|
||||||
pub public_url: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure the given value for `--public-url` is formatted correctly.
|
/// Ensure the given value for `--public-url` is formatted correctly.
|
||||||
|
|||||||
+19
-8
@@ -13,9 +13,9 @@ use crate::error::{Error, Result};
|
|||||||
#[derive(Clone, Debug, StructOpt)]
|
#[derive(Clone, Debug, StructOpt)]
|
||||||
#[structopt(name = "init")]
|
#[structopt(name = "init")]
|
||||||
pub struct Init {
|
pub struct Init {
|
||||||
/// Init project path
|
/// Init project name
|
||||||
#[structopt(default_value = ".")]
|
#[structopt(default_value = ".")]
|
||||||
path: String,
|
name: String,
|
||||||
|
|
||||||
/// Template path
|
/// Template path
|
||||||
#[structopt(default_value = "default", long)]
|
#[structopt(default_value = "default", long)]
|
||||||
@@ -24,18 +24,23 @@ pub struct Init {
|
|||||||
|
|
||||||
impl Init {
|
impl Init {
|
||||||
pub fn init(self) -> Result<()> {
|
pub fn init(self) -> Result<()> {
|
||||||
log::info!("🔧 Start to init a new project '{}'.", self.path);
|
if self.name.contains(".") {
|
||||||
|
log::error!("❗Unsupported project name.");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let project_path = PathBuf::from(&self.path);
|
log::info!("🔧 Start to init a new project '{}'.", self.name);
|
||||||
|
|
||||||
|
let project_path = PathBuf::from(&self.name);
|
||||||
|
|
||||||
if project_path.join("Cargo.toml").is_file() {
|
if project_path.join("Cargo.toml").is_file() {
|
||||||
log::warn!("Path '{}' is initialized.", self.path);
|
log::warn!("Folder '{}' is initialized.", self.name);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let output = Command::new("cargo")
|
||||||
.arg("init")
|
.arg("init")
|
||||||
.arg(&self.path)
|
.arg(&format!("./{}", self.name))
|
||||||
.arg("--bin")
|
.arg("--bin")
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
@@ -58,6 +63,11 @@ impl Init {
|
|||||||
let mut file = File::create(main_rs_file)?;
|
let mut file = File::create(main_rs_file)?;
|
||||||
file.write_all(&template_str.as_bytes())?;
|
file.write_all(&template_str.as_bytes())?;
|
||||||
|
|
||||||
|
let mut file = File::create(project_path.join("Dioxus.toml"))?;
|
||||||
|
let dioxus_conf = String::from(include_str!("../../template/config.toml"))
|
||||||
|
.replace("{project-name}", &self.name);
|
||||||
|
file.write_all(dioxus_conf.as_bytes())?;
|
||||||
|
|
||||||
// log::info!("🎯 Project initialization completed.");
|
// log::info!("🎯 Project initialization completed.");
|
||||||
|
|
||||||
if !Command::new("cargo")
|
if !Command::new("cargo")
|
||||||
@@ -72,8 +82,9 @@ impl Init {
|
|||||||
file.write_all("dioxus = { version = \"0.1.7\", features = [\"web\"] }".as_bytes())?;
|
file.write_all("dioxus = { version = \"0.1.7\", features = [\"web\"] }".as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("\n💡 Project initialized:");
|
println!("");
|
||||||
log::info!("🎯> cd {}", self.path);
|
log::info!("💡 Project initialized:");
|
||||||
|
log::info!("🎯> cd ./{}", self.name);
|
||||||
log::info!("🎯> dioxus serve");
|
log::info!("🎯> dioxus serve");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
+20
-8
@@ -1,4 +1,4 @@
|
|||||||
use crate::{cfg::ConfigOptsServe, server};
|
use crate::{cfg::ConfigOptsServe, gen_page, server};
|
||||||
use std::{io::Write, path::PathBuf};
|
use std::{io::Write, path::PathBuf};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
@@ -16,19 +16,31 @@ impl Serve {
|
|||||||
// change the relase state.
|
// change the relase state.
|
||||||
crate_config.with_release(self.serve.release);
|
crate_config.with_release(self.serve.release);
|
||||||
|
|
||||||
let dist_path = self.serve.dist.clone().unwrap_or(PathBuf::from("dist"));
|
crate::builder::build(&crate_config).expect("build failed");
|
||||||
|
|
||||||
crate::builder::build(&crate_config, dist_path.clone()).expect("build failed");
|
let serve_html = gen_page(&crate_config.dioxus_config, true);
|
||||||
|
|
||||||
let serve_html = String::from(include_str!("../../server/serve.html"));
|
let mut file = std::fs::File::create(
|
||||||
|
crate_config
|
||||||
let mut file =
|
.crate_dir
|
||||||
std::fs::File::create(crate_config.crate_dir.join(dist_path).join("index.html"))?;
|
.join(
|
||||||
|
crate_config
|
||||||
|
.dioxus_config
|
||||||
|
.web
|
||||||
|
.app
|
||||||
|
.out_dir
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(PathBuf::from("dist")),
|
||||||
|
)
|
||||||
|
.join("index.html"),
|
||||||
|
)?;
|
||||||
file.write_all(serve_html.as_bytes())?;
|
file.write_all(serve_html.as_bytes())?;
|
||||||
|
|
||||||
// start the develop server
|
// start the develop server
|
||||||
server::startup(crate_config.clone(), &self.serve).await?;
|
server::startup(crate_config.clone()).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn regen_page() {}
|
||||||
}
|
}
|
||||||
+62
-16
@@ -1,43 +1,76 @@
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::{fs::File, io::Read, path::PathBuf};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct DioxusConfig {
|
pub struct DioxusConfig {
|
||||||
application: ApplicationConfig,
|
pub application: ApplicationConfig,
|
||||||
web: WebConfig,
|
pub web: WebConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DioxusConfig {
|
||||||
|
pub fn load() -> crate::error::Result<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(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dioxus_conf_file = File::open(crate_dir.join("Dioxus.toml"))?;
|
||||||
|
let mut meta_str = String::new();
|
||||||
|
dioxus_conf_file.read_to_string(&mut meta_str)?;
|
||||||
|
|
||||||
|
match toml::from_str::<DioxusConfig>(&meta_str) {
|
||||||
|
Ok(v) => return Ok(v),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{}", e);
|
||||||
|
return Err(crate::error::Error::Unique(
|
||||||
|
"Dioxus.toml parse failed".into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ApplicationConfig {
|
pub struct ApplicationConfig {
|
||||||
name: String,
|
pub name: String,
|
||||||
platform: Vec<String>,
|
pub platforms: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct WebConfig {
|
pub struct WebConfig {
|
||||||
app: WebAppConfing,
|
pub app: WebAppConfing,
|
||||||
watcher: WebWatcherConfing,
|
pub watcher: WebWatcherConfing,
|
||||||
resource: WebResourceConfing,
|
pub resource: WebResourceConfing,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct WebAppConfing {
|
pub struct WebAppConfing {
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub out_dir: Option<PathBuf>,
|
||||||
|
pub static_dir: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct WebWatcherConfing {
|
pub struct WebWatcherConfing {
|
||||||
|
pub watch_path: Option<Vec<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct WebResourceConfing {
|
pub struct WebResourceConfing {
|
||||||
|
pub dev: WebDevResourceConfing,
|
||||||
|
pub style: Option<Vec<PathBuf>>,
|
||||||
|
pub script: Option<Vec<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct WebDevResourceConfing {
|
||||||
|
pub style: Option<Vec<PathBuf>>,
|
||||||
|
pub script: Option<Vec<PathBuf>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CrateConfig {
|
pub struct CrateConfig {
|
||||||
@@ -48,6 +81,7 @@ pub struct CrateConfig {
|
|||||||
pub static_dir: PathBuf,
|
pub static_dir: PathBuf,
|
||||||
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
||||||
pub executable: ExecutableType,
|
pub executable: ExecutableType,
|
||||||
|
pub dioxus_config: DioxusConfig,
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,12 +94,23 @@ pub enum ExecutableType {
|
|||||||
|
|
||||||
impl CrateConfig {
|
impl CrateConfig {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
|
let dioxus_config = DioxusConfig::load()?;
|
||||||
|
|
||||||
let crate_dir = crate::cargo::crate_root()?;
|
let crate_dir = crate::cargo::crate_root()?;
|
||||||
let workspace_dir = crate::cargo::workspace_root()?;
|
let workspace_dir = crate::cargo::workspace_root()?;
|
||||||
let target_dir = workspace_dir.join("target");
|
let target_dir = workspace_dir.join("target");
|
||||||
let out_dir = crate_dir.join("public");
|
|
||||||
|
let out_dir = match dioxus_config.web.app.out_dir {
|
||||||
|
Some(ref v) => crate_dir.join(v),
|
||||||
|
None => crate_dir.join("dist"),
|
||||||
|
};
|
||||||
|
|
||||||
let cargo_def = &crate_dir.join("Cargo.toml");
|
let cargo_def = &crate_dir.join("Cargo.toml");
|
||||||
let static_dir = crate_dir.join("static");
|
|
||||||
|
let static_dir = match dioxus_config.web.app.static_dir {
|
||||||
|
Some(ref v) => crate_dir.join(v),
|
||||||
|
None => crate_dir.join("static"),
|
||||||
|
};
|
||||||
|
|
||||||
let manifest = cargo_toml::Manifest::from_path(&cargo_def).unwrap();
|
let manifest = cargo_toml::Manifest::from_path(&cargo_def).unwrap();
|
||||||
|
|
||||||
@@ -96,6 +141,7 @@ impl CrateConfig {
|
|||||||
manifest,
|
manifest,
|
||||||
executable,
|
executable,
|
||||||
release,
|
release,
|
||||||
|
dioxus_config,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,4 +170,4 @@ impl CrateConfig {
|
|||||||
// self.release = options.release;
|
// self.release = options.release;
|
||||||
// self.out_dir = tempfile::Builder::new().tempdir().expect("").into_path();
|
// self.out_dir = tempfile::Builder::new().tempdir().expect("").into_path();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head></head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
Sorry, but building your application failed.
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
Here's the error:
|
|
||||||
</p>
|
|
||||||
<code>
|
|
||||||
{err}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
+33
-21
@@ -13,7 +13,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
||||||
use crate::{builder, CrateConfig};
|
use crate::{builder, crate_root, CrateConfig};
|
||||||
|
|
||||||
struct WsRelodState {
|
struct WsRelodState {
|
||||||
update: bool,
|
update: bool,
|
||||||
@@ -25,42 +25,54 @@ impl WsRelodState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(
|
pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
|
||||||
config: CrateConfig,
|
|
||||||
opts: &crate::cfg::ConfigOptsServe,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
log::info!("🚀 Starting development server...");
|
log::info!("🚀 Starting development server...");
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
let dist_path = opts.dist.clone().unwrap_or(PathBuf::from("dist"));
|
let dist_path = config.out_dir.clone();
|
||||||
|
|
||||||
// file watcher: check file change
|
// file watcher: check file change
|
||||||
let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap();
|
let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
|
||||||
watcher
|
watcher
|
||||||
.watch(
|
.watch(config.crate_dir.clone(), notify::RecursiveMode::Recursive)
|
||||||
config.crate_dir.join("src").clone(),
|
|
||||||
notify::RecursiveMode::Recursive,
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let ws_reload_state = Arc::new(Mutex::new(WsRelodState { update: false }));
|
let ws_reload_state = Arc::new(Mutex::new(WsRelodState { update: false }));
|
||||||
|
|
||||||
let watcher_conf = config.clone();
|
let watcher_conf = config.clone();
|
||||||
let watcher_ws_state = ws_reload_state.clone();
|
let watcher_ws_state = ws_reload_state.clone();
|
||||||
let watcher_dist_path = dist_path.clone();
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let allow_watch_path = watcher_conf
|
||||||
|
.dioxus_config
|
||||||
|
.web
|
||||||
|
.watcher
|
||||||
|
.watch_path
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(vec![PathBuf::from("src")]);
|
||||||
|
let crate_dir = watcher_conf.crate_dir.clone();
|
||||||
loop {
|
loop {
|
||||||
if let Ok(v) = rx.recv() {
|
if let Ok(v) = rx.recv() {
|
||||||
match v {
|
match v {
|
||||||
DebouncedEvent::Create(_)
|
DebouncedEvent::Create(e)
|
||||||
| DebouncedEvent::Write(_)
|
| DebouncedEvent::Write(e)
|
||||||
| DebouncedEvent::Remove(_)
|
| DebouncedEvent::Remove(e)
|
||||||
| DebouncedEvent::Rename(_, _) => {
|
| DebouncedEvent::Rename(e, _) => {
|
||||||
if let Ok(_) = builder::build(&watcher_conf, watcher_dist_path.clone()) {
|
let mut reload = false;
|
||||||
// change the websocket reload state to true;
|
for path in &allow_watch_path {
|
||||||
// the page will auto-reload.
|
let temp = crate_dir.clone().join(path);
|
||||||
watcher_ws_state.lock().unwrap().change();
|
if e.starts_with(temp) {
|
||||||
|
reload = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if reload {
|
||||||
|
if let Ok(_) = builder::build(&watcher_conf) {
|
||||||
|
// change the websocket reload state to true;
|
||||||
|
// the page will auto-reload.
|
||||||
|
watcher_ws_state.lock().unwrap().change();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -70,7 +82,7 @@ pub async fn startup(
|
|||||||
});
|
});
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/ws", get(ws_handler))
|
.route("/_dioxus/ws", get(ws_handler))
|
||||||
.fallback(
|
.fallback(
|
||||||
get_service(ServeDir::new(config.crate_dir.join(&dist_path))).handle_error(
|
get_service(ServeDir::new(config.crate_dir.join(&dist_path))).handle_error(
|
||||||
|error: std::io::Error| async move {
|
|error: std::io::Error| async move {
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Dioxus-CLI Dev Server</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="main"></div>
|
|
||||||
|
|
||||||
<!-- Note the usage of `type=module` here as this is an ES6 module -->
|
|
||||||
<script type="module">
|
|
||||||
import init from "./assets/module.js";
|
|
||||||
init("./assets/module_bg.wasm");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
(function () {
|
|
||||||
var protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
||||||
var url = protocol + "//" + window.location.host + "/ws";
|
|
||||||
var poll_interval = 2000;
|
|
||||||
var reload_upon_connect = () => {
|
|
||||||
window.setTimeout(() => {
|
|
||||||
var ws = new WebSocket(url);
|
|
||||||
ws.onopen = () => window.location.reload();
|
|
||||||
ws.onclose = reload_upon_connect;
|
|
||||||
}, poll_interval);
|
|
||||||
};
|
|
||||||
|
|
||||||
var ws = new WebSocket(url);
|
|
||||||
ws.onmessage = (ev) => {
|
|
||||||
if (ev.data == "reload") {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ws.onclose = reload_upon_connect;
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,9 +1,38 @@
|
|||||||
[package]
|
[application]
|
||||||
name = "{project}"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# App (Project) Name
|
||||||
|
name = "{project-name}"
|
||||||
|
|
||||||
[dependencies]
|
# Dioxus App Support Platform
|
||||||
dioxus = { version = "0.1.7", features = ["web"] }
|
# desktop, web, mobile, ssr
|
||||||
|
platforms = ["web"]
|
||||||
|
|
||||||
|
[web.app]
|
||||||
|
|
||||||
|
# HTML title tag content
|
||||||
|
title = "dioxus | ⛺"
|
||||||
|
|
||||||
|
# Web `build` & `serve` dist path
|
||||||
|
out_dir = "dist"
|
||||||
|
|
||||||
|
# resource (static) file folder
|
||||||
|
static_dir = "static"
|
||||||
|
|
||||||
|
[web.watcher]
|
||||||
|
|
||||||
|
watch_path = ["src"]
|
||||||
|
|
||||||
|
# include `assets` in web platform
|
||||||
|
[web.resource]
|
||||||
|
|
||||||
|
# CSS style file
|
||||||
|
style = []
|
||||||
|
|
||||||
|
# Javascript code file
|
||||||
|
script = []
|
||||||
|
|
||||||
|
[web.resource.dev]
|
||||||
|
|
||||||
|
# Javascript code file
|
||||||
|
# serve: [dev-server] only
|
||||||
|
script = []
|
||||||
@@ -8,8 +8,8 @@ fn app(cx: Scope) -> Element {
|
|||||||
cx.render(rsx! (
|
cx.render(rsx! (
|
||||||
div {
|
div {
|
||||||
style: "text-align: center;",
|
style: "text-align: center;",
|
||||||
h2 { "🌗🚀 Dioxus" }
|
h1 { "🌗 Dioxus 🚀" }
|
||||||
p { strong { "Frontend that scales." } }
|
h3 { "Frontend that scales." }
|
||||||
p { "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." }
|
p { "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." }
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|||||||
Reference in new issue
Block a user