fix(serve): fixed long rebuilds with dx serve
This commit is contained in:
9 files changed
+213
-125
No files matched your search
@@ -448,6 +448,22 @@ impl CrateConfig {
|
|||||||
self.crate_dir.join(&self.dioxus_config.application.out_dir)
|
self.crate_dir.join(&self.dioxus_config.application.out_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compose an out directory for the fullstack platform. See `out_dir()`
|
||||||
|
/// method.
|
||||||
|
pub fn fullstack_out_dir(&self) -> PathBuf {
|
||||||
|
self.crate_dir.join(".dioxus")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compose a target directory for the server (fullstack-only?).
|
||||||
|
pub fn server_target_dir(&self) -> PathBuf {
|
||||||
|
self.fullstack_out_dir().join("ssr")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compose a target directory for the client (fullstack-only?).
|
||||||
|
pub fn client_target_dir(&self) -> PathBuf {
|
||||||
|
self.fullstack_out_dir().join("web")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_example(&mut self, example_name: String) -> &mut Self {
|
pub fn as_example(&mut self, example_name: String) -> &mut Self {
|
||||||
self.executable = ExecutableType::Example(example_name);
|
self.executable = ExecutableType::Example(example_name);
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use indicatif::{ProgressBar, ProgressStyle};
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use manganis_cli_support::{AssetManifest, ManganisSupportGuard};
|
use manganis_cli_support::{AssetManifest, ManganisSupportGuard};
|
||||||
use std::{
|
use std::{
|
||||||
|
env,
|
||||||
fs::{copy, create_dir_all, File},
|
fs::{copy, create_dir_all, File},
|
||||||
io::Read,
|
io::Read,
|
||||||
panic,
|
panic,
|
||||||
@@ -30,7 +31,45 @@ pub struct BuildResult {
|
|||||||
pub assets: Option<AssetManifest>,
|
pub assets: Option<AssetManifest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildResult> {
|
/// This trait is only created for the convenient and concise way to set
|
||||||
|
/// `RUSTFLAGS` environment variable for the `subprocess::Exec`.
|
||||||
|
pub trait ExecWithRustFlagsSetter {
|
||||||
|
fn set_rust_flags(self, rust_flags: Option<String>) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecWithRustFlagsSetter for subprocess::Exec {
|
||||||
|
/// Sets (appends to, if already set) `RUSTFLAGS` environment variable if
|
||||||
|
/// `rust_flags` is not `None`.
|
||||||
|
fn set_rust_flags(self, rust_flags: Option<String>) -> Self {
|
||||||
|
if let Some(rust_flags) = rust_flags {
|
||||||
|
// Some `RUSTFLAGS` might be already set in the environment or provided
|
||||||
|
// by the user. They should take higher priority than the default flags.
|
||||||
|
// If no default flags are provided, then there is no point in
|
||||||
|
// redefining the environment variable with the same value, if it is
|
||||||
|
// even set. If no custom flags are set, then there is no point in
|
||||||
|
// adding the unnecessary whitespace to the command.
|
||||||
|
self.env(
|
||||||
|
"RUSTFLAGS",
|
||||||
|
if let Ok(custom_rust_flags) = env::var("RUSTFLAGS") {
|
||||||
|
rust_flags + " " + custom_rust_flags.as_str()
|
||||||
|
} else {
|
||||||
|
rust_flags
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build client (WASM).
|
||||||
|
/// Note: `rust_flags` argument is only used for the fullstack platform.
|
||||||
|
pub fn build(
|
||||||
|
config: &CrateConfig,
|
||||||
|
_: bool,
|
||||||
|
skip_assets: bool,
|
||||||
|
rust_flags: Option<String>,
|
||||||
|
) -> Result<BuildResult> {
|
||||||
// [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
|
||||||
// [3] Wasm-bindgen the .wasm file, 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
|
||||||
@@ -72,6 +111,7 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
let cmd = subprocess::Exec::cmd("cargo")
|
let cmd = subprocess::Exec::cmd("cargo")
|
||||||
|
.set_rust_flags(rust_flags)
|
||||||
.env("CARGO_TARGET_DIR", target_dir)
|
.env("CARGO_TARGET_DIR", target_dir)
|
||||||
.cwd(crate_dir)
|
.cwd(crate_dir)
|
||||||
.arg("build")
|
.arg("build")
|
||||||
@@ -79,6 +119,8 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
.arg("wasm32-unknown-unknown")
|
.arg("wasm32-unknown-unknown")
|
||||||
.arg("--message-format=json");
|
.arg("--message-format=json");
|
||||||
|
|
||||||
|
// TODO: make the initial variable mutable to simplify all the expressions
|
||||||
|
// below. Look inside the `build_desktop()` as an example.
|
||||||
let cmd = if config.release {
|
let cmd = if config.release {
|
||||||
cmd.arg("--release")
|
cmd.arg("--release")
|
||||||
} else {
|
} else {
|
||||||
@@ -283,10 +325,13 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Note: `rust_flags` argument is only used for the fullstack platform
|
||||||
|
/// (server).
|
||||||
pub fn build_desktop(
|
pub fn build_desktop(
|
||||||
config: &CrateConfig,
|
config: &CrateConfig,
|
||||||
_is_serve: bool,
|
_is_serve: bool,
|
||||||
skip_assets: bool,
|
skip_assets: bool,
|
||||||
|
rust_flags: Option<String>,
|
||||||
) -> Result<BuildResult> {
|
) -> Result<BuildResult> {
|
||||||
log::info!("🚅 Running build [Desktop] command...");
|
log::info!("🚅 Running build [Desktop] command...");
|
||||||
|
|
||||||
@@ -296,6 +341,7 @@ pub fn build_desktop(
|
|||||||
let _manganis_support = ManganisSupportGuard::default();
|
let _manganis_support = ManganisSupportGuard::default();
|
||||||
|
|
||||||
let mut cmd = subprocess::Exec::cmd("cargo")
|
let mut cmd = subprocess::Exec::cmd("cargo")
|
||||||
|
.set_rust_flags(rust_flags)
|
||||||
.env("CARGO_TARGET_DIR", &config.target_dir)
|
.env("CARGO_TARGET_DIR", &config.target_dir)
|
||||||
.cwd(&config.crate_dir)
|
.cwd(&config.crate_dir)
|
||||||
.arg("build")
|
.arg("build")
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use crate::assets::WebAssetConfigDropGuard;
|
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
use crate::plugin::PluginManager;
|
use crate::plugin::PluginManager;
|
||||||
use crate::server::fullstack::FullstackServerEnvGuard;
|
use crate::{assets::WebAssetConfigDropGuard, server::fullstack};
|
||||||
use crate::server::fullstack::FullstackWebEnvGuard;
|
|
||||||
use dioxus_cli_config::Platform;
|
use dioxus_cli_config::Platform;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -16,7 +14,13 @@ pub struct Build {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Build {
|
impl Build {
|
||||||
pub fn build(self, bin: Option<PathBuf>, target_dir: Option<&std::path::Path>) -> Result<()> {
|
/// Note: `rust_flags` argument is only used for the fullstack platform.
|
||||||
|
pub fn build(
|
||||||
|
self,
|
||||||
|
bin: Option<PathBuf>,
|
||||||
|
target_dir: Option<&std::path::Path>,
|
||||||
|
rust_flags: Option<String>,
|
||||||
|
) -> Result<()> {
|
||||||
let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?;
|
let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?;
|
||||||
if let Some(target_dir) = target_dir {
|
if let Some(target_dir) = target_dir {
|
||||||
crate_config.target_dir = target_dir.to_path_buf();
|
crate_config.target_dir = target_dir.to_path_buf();
|
||||||
@@ -53,16 +57,23 @@ impl Build {
|
|||||||
// let _ = PluginManager::on_build_start(&crate_config, &platform);
|
// let _ = PluginManager::on_build_start(&crate_config, &platform);
|
||||||
|
|
||||||
let build_result = match platform {
|
let build_result = match platform {
|
||||||
Platform::Web => crate::builder::build(&crate_config, false, self.build.skip_assets)?,
|
Platform::Web => {
|
||||||
|
// `rust_flags` are used by fullstack's client build.
|
||||||
|
crate::builder::build(&crate_config, false, self.build.skip_assets, rust_flags)?
|
||||||
|
}
|
||||||
Platform::Desktop => {
|
Platform::Desktop => {
|
||||||
crate::builder::build_desktop(&crate_config, false, self.build.skip_assets)?
|
// Since desktop platform doesn't use `rust_flags`, this
|
||||||
|
// argument is explicitly set to `None`.
|
||||||
|
crate::builder::build_desktop(&crate_config, false, self.build.skip_assets, None)?
|
||||||
}
|
}
|
||||||
Platform::Fullstack => {
|
Platform::Fullstack => {
|
||||||
// Fullstack mode must be built with web configs on the desktop (server) binary as well as the web binary
|
// Fullstack mode must be built with web configs on the desktop
|
||||||
|
// (server) binary as well as the web binary
|
||||||
let _config = WebAssetConfigDropGuard::new();
|
let _config = WebAssetConfigDropGuard::new();
|
||||||
|
let client_rust_flags = fullstack::client_rust_flags(&self.build);
|
||||||
|
let server_rust_flags = fullstack::server_rust_flags(&self.build);
|
||||||
{
|
{
|
||||||
let mut web_config = crate_config.clone();
|
let mut web_config = crate_config.clone();
|
||||||
let _gaurd = FullstackWebEnvGuard::new(&self.build);
|
|
||||||
let web_feature = self.build.client_feature;
|
let web_feature = self.build.client_feature;
|
||||||
let features = &mut web_config.features;
|
let features = &mut web_config.features;
|
||||||
match features {
|
match features {
|
||||||
@@ -71,7 +82,12 @@ impl Build {
|
|||||||
}
|
}
|
||||||
None => web_config.features = Some(vec![web_feature]),
|
None => web_config.features = Some(vec![web_feature]),
|
||||||
};
|
};
|
||||||
crate::builder::build(&web_config, false, self.build.skip_assets)?;
|
crate::builder::build(
|
||||||
|
&web_config,
|
||||||
|
false,
|
||||||
|
self.build.skip_assets,
|
||||||
|
Some(client_rust_flags),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut desktop_config = crate_config.clone();
|
let mut desktop_config = crate_config.clone();
|
||||||
@@ -83,9 +99,12 @@ impl Build {
|
|||||||
}
|
}
|
||||||
None => desktop_config.features = Some(vec![desktop_feature]),
|
None => desktop_config.features = Some(vec![desktop_feature]),
|
||||||
};
|
};
|
||||||
let _gaurd =
|
crate::builder::build_desktop(
|
||||||
FullstackServerEnvGuard::new(self.build.force_debug, self.build.release);
|
&desktop_config,
|
||||||
crate::builder::build_desktop(&desktop_config, false, self.build.skip_assets)?
|
false,
|
||||||
|
self.build.skip_assets,
|
||||||
|
Some(server_rust_flags),
|
||||||
|
)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ impl Bundle {
|
|||||||
crate_config.set_cargo_args(self.build.cargo_args);
|
crate_config.set_cargo_args(self.build.cargo_args);
|
||||||
|
|
||||||
// build the desktop app
|
// build the desktop app
|
||||||
build_desktop(&crate_config, false, false)?;
|
// Since the `bundle()` function is only run for the desktop platform,
|
||||||
|
// the `rust_flags` argument is set to `None`.
|
||||||
|
build_desktop(&crate_config, false, false, None)?;
|
||||||
|
|
||||||
// copy the binary to the out dir
|
// copy the binary to the out dir
|
||||||
let package = crate_config.manifest.package.as_ref().unwrap();
|
let package = crate_config.manifest.package.as_ref().unwrap();
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ impl Clean {
|
|||||||
return custom_error!("Cargo clean failed.");
|
return custom_error!("Cargo clean failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let out_dir = crate_config.dioxus_config.application.out_dir;
|
let out_dir = &crate_config.dioxus_config.application.out_dir;
|
||||||
if crate_config.crate_dir.join(&out_dir).is_dir() {
|
if crate_config.crate_dir.join(out_dir).is_dir() {
|
||||||
remove_dir_all(crate_config.crate_dir.join(&out_dir))?;
|
remove_dir_all(crate_config.crate_dir.join(out_dir))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fullstack_out_dir = crate_config.crate_dir.join(".dioxus");
|
let fullstack_out_dir = crate_config.fullstack_out_dir();
|
||||||
|
|
||||||
if fullstack_out_dir.is_dir() {
|
if fullstack_out_dir.is_dir() {
|
||||||
remove_dir_all(fullstack_out_dir)?;
|
remove_dir_all(fullstack_out_dir)?;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
match action {
|
match action {
|
||||||
Build(opts) => opts
|
Build(opts) => opts
|
||||||
.build(Some(bin.clone()), None)
|
.build(Some(bin.clone()), None, None)
|
||||||
.context(error_wrapper("Building project failed")),
|
.context(error_wrapper("Building project failed")),
|
||||||
|
|
||||||
Clean(opts) => opts
|
Clean(opts) => opts
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use dioxus_hot_reload::HotReloadMsg;
|
|||||||
use dioxus_html::HtmlCtx;
|
use dioxus_html::HtmlCtx;
|
||||||
use dioxus_rsx::hot_reload::*;
|
use dioxus_rsx::hot_reload::*;
|
||||||
use interprocess_docfix::local_socket::LocalSocketListener;
|
use interprocess_docfix::local_socket::LocalSocketListener;
|
||||||
|
use std::fs::create_dir_all;
|
||||||
use std::{
|
use std::{
|
||||||
process::{Child, Command},
|
process::{Child, Command},
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex, RwLock},
|
||||||
@@ -109,6 +110,7 @@ async fn start_desktop_hot_reload(hot_reload_state: HotReloadState) -> Result<()
|
|||||||
.exec()
|
.exec()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let target_dir = metadata.target_directory.as_std_path();
|
let target_dir = metadata.target_directory.as_std_path();
|
||||||
|
let _ = create_dir_all(target_dir); // `_all` is for good measure and future-proofness.
|
||||||
let path = target_dir.join("dioxusin");
|
let path = target_dir.join("dioxusin");
|
||||||
clear_paths(&path);
|
clear_paths(&path);
|
||||||
match LocalSocketListener::bind(path) {
|
match LocalSocketListener::bind(path) {
|
||||||
@@ -213,9 +215,14 @@ fn send_msg(msg: HotReloadMsg, channel: &mut impl std::io::Write) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_desktop(config: &CrateConfig, skip_assets: bool) -> Result<(RAIIChild, BuildResult)> {
|
fn start_desktop(
|
||||||
|
config: &CrateConfig,
|
||||||
|
skip_assets: bool,
|
||||||
|
rust_flags: Option<String>,
|
||||||
|
) -> Result<(RAIIChild, BuildResult)> {
|
||||||
// Run the desktop application
|
// Run the desktop application
|
||||||
let result = crate::builder::build_desktop(config, true, skip_assets)?;
|
// Only used for the fullstack platform,
|
||||||
|
let result = crate::builder::build_desktop(config, true, skip_assets, rust_flags)?;
|
||||||
|
|
||||||
match &config.executable {
|
match &config.executable {
|
||||||
ExecutableType::Binary(name)
|
ExecutableType::Binary(name)
|
||||||
@@ -242,9 +249,15 @@ pub(crate) struct DesktopPlatform {
|
|||||||
skip_assets: bool,
|
skip_assets: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform for DesktopPlatform {
|
impl DesktopPlatform {
|
||||||
fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result<Self> {
|
/// `rust_flags` argument is added because it is used by the
|
||||||
let (child, first_build_result) = start_desktop(config, serve.skip_assets)?;
|
/// `DesktopPlatform`'s implementation of the `Platform::start()`.
|
||||||
|
pub fn start_with_options(
|
||||||
|
config: &CrateConfig,
|
||||||
|
serve: &ConfigOptsServe,
|
||||||
|
rust_flags: Option<String>,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let (child, first_build_result) = start_desktop(config, serve.skip_assets, rust_flags)?;
|
||||||
|
|
||||||
log::info!("🚀 Starting development server...");
|
log::info!("🚀 Starting development server...");
|
||||||
|
|
||||||
@@ -265,14 +278,38 @@ impl Platform for DesktopPlatform {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rebuild(&mut self, config: &CrateConfig) -> Result<BuildResult> {
|
/// `rust_flags` argument is added because it is used by the
|
||||||
|
/// `DesktopPlatform`'s implementation of the `Platform::rebuild()`.
|
||||||
|
pub fn rebuild_with_options(
|
||||||
|
&mut self,
|
||||||
|
config: &CrateConfig,
|
||||||
|
rust_flags: Option<String>,
|
||||||
|
) -> Result<BuildResult> {
|
||||||
self.currently_running_child.0.kill()?;
|
self.currently_running_child.0.kill()?;
|
||||||
let (child, result) = start_desktop(config, self.skip_assets)?;
|
let (child, result) = start_desktop(config, self.skip_assets, rust_flags)?;
|
||||||
self.currently_running_child = child;
|
self.currently_running_child = child;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Platform for DesktopPlatform {
|
||||||
|
fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result<Self> {
|
||||||
|
// See `start_with_options()`'s docs for the explanation why the code
|
||||||
|
// was moved there.
|
||||||
|
// Since desktop platform doesn't use `rust_flags`, this argument is
|
||||||
|
// explicitly set to `None`.
|
||||||
|
DesktopPlatform::start_with_options(config, serve, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rebuild(&mut self, config: &CrateConfig) -> Result<BuildResult> {
|
||||||
|
// See `rebuild_with_options()`'s docs for the explanation why the code
|
||||||
|
// was moved there.
|
||||||
|
// Since desktop platform doesn't use `rust_flags`, this argument is
|
||||||
|
// explicitly set to `None`.
|
||||||
|
DesktopPlatform::rebuild_with_options(self, config, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct RAIIChild(Child);
|
struct RAIIChild(Child);
|
||||||
|
|
||||||
impl Drop for RAIIChild {
|
impl Drop for RAIIChild {
|
||||||
|
|||||||
@@ -1,13 +1,38 @@
|
|||||||
use dioxus_cli_config::CrateConfig;
|
use dioxus_cli_config::CrateConfig;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::WebAssetConfigDropGuard,
|
|
||||||
cfg::{ConfigOptsBuild, ConfigOptsServe},
|
cfg::{ConfigOptsBuild, ConfigOptsServe},
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{desktop, Platform};
|
use super::{desktop, Platform};
|
||||||
|
|
||||||
|
static CLIENT_RUST_FLAGS: &str = "-C debuginfo=none -C strip=debuginfo";
|
||||||
|
// The `opt-level=2` increases build times, but can noticeably decrease time
|
||||||
|
// between saving changes and being able to interact with an app. The "overall"
|
||||||
|
// time difference (between having and not having the optimization) can be
|
||||||
|
// almost imperceptible (~1 s) but also can be very noticeable (~6 s) — depends
|
||||||
|
// on setup (hardware, OS, browser, idle load).
|
||||||
|
static SERVER_RUST_FLAGS: &str = "-C opt-level=2";
|
||||||
|
static DEBUG_RUST_FLAG: &str = "-C debug-assertions";
|
||||||
|
|
||||||
|
fn rust_flags(build: &ConfigOptsBuild, base_flags: &str) -> String {
|
||||||
|
let mut rust_flags = base_flags.to_string();
|
||||||
|
if !build.release {
|
||||||
|
rust_flags += " ";
|
||||||
|
rust_flags += DEBUG_RUST_FLAG;
|
||||||
|
};
|
||||||
|
rust_flags
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn client_rust_flags(build: &ConfigOptsBuild) -> String {
|
||||||
|
rust_flags(build, CLIENT_RUST_FLAGS)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn server_rust_flags(build: &ConfigOptsBuild) -> String {
|
||||||
|
rust_flags(build, SERVER_RUST_FLAGS)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
||||||
desktop::startup_with_platform::<FullstackPlatform>(config, serve).await
|
desktop::startup_with_platform::<FullstackPlatform>(config, serve).await
|
||||||
}
|
}
|
||||||
@@ -17,15 +42,29 @@ fn start_web_build_thread(
|
|||||||
serve: &ConfigOptsServe,
|
serve: &ConfigOptsServe,
|
||||||
) -> std::thread::JoinHandle<Result<()>> {
|
) -> std::thread::JoinHandle<Result<()>> {
|
||||||
let serve = serve.clone();
|
let serve = serve.clone();
|
||||||
let target_directory = config.crate_dir.join(".dioxus").join("web");
|
let target_directory = config.client_target_dir();
|
||||||
std::fs::create_dir_all(&target_directory).unwrap();
|
std::fs::create_dir_all(&target_directory).unwrap();
|
||||||
std::thread::spawn(move || build_web(serve, &target_directory))
|
std::thread::spawn(move || build_web(serve, &target_directory))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_desktop_config(config: &CrateConfig, serve: &ConfigOptsServe) -> CrateConfig {
|
||||||
|
let mut desktop_config = config.clone();
|
||||||
|
desktop_config.target_dir = config.server_target_dir();
|
||||||
|
let desktop_feature = serve.server_feature.clone();
|
||||||
|
let features = &mut desktop_config.features;
|
||||||
|
match features {
|
||||||
|
Some(features) => {
|
||||||
|
features.push(desktop_feature);
|
||||||
|
}
|
||||||
|
None => desktop_config.features = Some(vec![desktop_feature]),
|
||||||
|
};
|
||||||
|
desktop_config
|
||||||
|
}
|
||||||
|
|
||||||
struct FullstackPlatform {
|
struct FullstackPlatform {
|
||||||
serve: ConfigOptsServe,
|
serve: ConfigOptsServe,
|
||||||
desktop: desktop::DesktopPlatform,
|
desktop: desktop::DesktopPlatform,
|
||||||
_config: WebAssetConfigDropGuard,
|
server_rust_flags: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform for FullstackPlatform {
|
impl Platform for FullstackPlatform {
|
||||||
@@ -35,17 +74,13 @@ impl Platform for FullstackPlatform {
|
|||||||
{
|
{
|
||||||
let thread_handle = start_web_build_thread(config, serve);
|
let thread_handle = start_web_build_thread(config, serve);
|
||||||
|
|
||||||
let mut desktop_config = config.clone();
|
let desktop_config = make_desktop_config(config, serve);
|
||||||
let desktop_feature = serve.server_feature.clone();
|
let server_rust_flags = server_rust_flags(&serve.clone().into());
|
||||||
let features = &mut desktop_config.features;
|
let desktop = desktop::DesktopPlatform::start_with_options(
|
||||||
match features {
|
&desktop_config,
|
||||||
Some(features) => {
|
serve,
|
||||||
features.push(desktop_feature);
|
Some(server_rust_flags.clone()),
|
||||||
}
|
)?;
|
||||||
None => desktop_config.features = Some(vec![desktop_feature]),
|
|
||||||
};
|
|
||||||
let config = WebAssetConfigDropGuard::new();
|
|
||||||
let desktop = desktop::DesktopPlatform::start(&desktop_config, serve)?;
|
|
||||||
thread_handle
|
thread_handle
|
||||||
.join()
|
.join()
|
||||||
.map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
|
.map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
|
||||||
@@ -53,25 +88,16 @@ impl Platform for FullstackPlatform {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
desktop,
|
desktop,
|
||||||
serve: serve.clone(),
|
serve: serve.clone(),
|
||||||
_config: config,
|
server_rust_flags,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rebuild(&mut self, crate_config: &CrateConfig) -> Result<crate::BuildResult> {
|
fn rebuild(&mut self, crate_config: &CrateConfig) -> Result<crate::BuildResult> {
|
||||||
let thread_handle = start_web_build_thread(crate_config, &self.serve);
|
let thread_handle = start_web_build_thread(crate_config, &self.serve);
|
||||||
let result = {
|
let desktop_config = make_desktop_config(crate_config, &self.serve);
|
||||||
let mut desktop_config = crate_config.clone();
|
let result = self
|
||||||
let desktop_feature = self.serve.server_feature.clone();
|
.desktop
|
||||||
let features = &mut desktop_config.features;
|
.rebuild_with_options(&desktop_config, Some(self.server_rust_flags.clone()));
|
||||||
match features {
|
|
||||||
Some(features) => {
|
|
||||||
features.push(desktop_feature);
|
|
||||||
}
|
|
||||||
None => desktop_config.features = Some(vec![desktop_feature]),
|
|
||||||
};
|
|
||||||
let _gaurd = FullstackServerEnvGuard::new(self.serve.force_debug, self.serve.release);
|
|
||||||
self.desktop.rebuild(&desktop_config)
|
|
||||||
};
|
|
||||||
thread_handle
|
thread_handle
|
||||||
.join()
|
.join()
|
||||||
.map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
|
.map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
|
||||||
@@ -91,74 +117,12 @@ fn build_web(serve: ConfigOptsServe, target_directory: &std::path::Path) -> Resu
|
|||||||
};
|
};
|
||||||
web_config.platform = Some(dioxus_cli_config::Platform::Web);
|
web_config.platform = Some(dioxus_cli_config::Platform::Web);
|
||||||
|
|
||||||
let _gaurd = FullstackWebEnvGuard::new(&web_config);
|
crate::cli::build::Build {
|
||||||
crate::cli::build::Build { build: web_config }.build(None, Some(target_directory))
|
build: web_config.clone(),
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// This reduces a hello world from ~40MB to ~2MB
|
|
||||||
pub(crate) struct FullstackWebEnvGuard {
|
|
||||||
old_rustflags: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FullstackWebEnvGuard {
|
|
||||||
pub fn new(serve: &ConfigOptsBuild) -> Self {
|
|
||||||
Self {
|
|
||||||
old_rustflags: (!serve.force_debug).then(|| {
|
|
||||||
let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default();
|
|
||||||
let debug_assertions = if serve.release {
|
|
||||||
""
|
|
||||||
} else {
|
|
||||||
" -C debug-assertions"
|
|
||||||
};
|
|
||||||
|
|
||||||
std::env::set_var(
|
|
||||||
"RUSTFLAGS",
|
|
||||||
format!(
|
|
||||||
"{old_rustflags} -C debuginfo=none -C strip=debuginfo{debug_assertions}"
|
|
||||||
),
|
|
||||||
);
|
|
||||||
old_rustflags
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for FullstackWebEnvGuard {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(old_rustflags) = self.old_rustflags.take() {
|
|
||||||
std::env::set_var("RUSTFLAGS", old_rustflags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// This reduces a hello world from ~40MB to ~2MB
|
|
||||||
pub(crate) struct FullstackServerEnvGuard {
|
|
||||||
old_rustflags: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FullstackServerEnvGuard {
|
|
||||||
pub fn new(debug: bool, release: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
old_rustflags: (!debug).then(|| {
|
|
||||||
let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default();
|
|
||||||
let debug_assertions = if release { "" } else { " -C debug-assertions" };
|
|
||||||
|
|
||||||
std::env::set_var(
|
|
||||||
"RUSTFLAGS",
|
|
||||||
format!("{old_rustflags} -C opt-level=2 {debug_assertions}"),
|
|
||||||
);
|
|
||||||
old_rustflags
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for FullstackServerEnvGuard {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(old_rustflags) = self.old_rustflags.take() {
|
|
||||||
std::env::set_var("RUSTFLAGS", old_rustflags);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.build(
|
||||||
|
None,
|
||||||
|
Some(target_directory),
|
||||||
|
Some(client_rust_flags(&web_config)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,9 @@ pub async fn serve(
|
|||||||
skip_assets: bool,
|
skip_assets: bool,
|
||||||
hot_reload_state: Option<HotReloadState>,
|
hot_reload_state: Option<HotReloadState>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let first_build_result = crate::builder::build(&config, false, skip_assets)?;
|
// Since web platform doesn't use `rust_flags`, this argument is explicitly
|
||||||
|
// set to `None`.
|
||||||
|
let first_build_result = crate::builder::build(&config, false, skip_assets, None)?;
|
||||||
|
|
||||||
// generate dev-index page
|
// generate dev-index page
|
||||||
Serve::regen_dev_page(&config, first_build_result.assets.as_ref())?;
|
Serve::regen_dev_page(&config, first_build_result.assets.as_ref())?;
|
||||||
@@ -447,7 +449,9 @@ async fn ws_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(config: &CrateConfig, reload_tx: &Sender<()>, skip_assets: bool) -> Result<BuildResult> {
|
fn build(config: &CrateConfig, reload_tx: &Sender<()>, skip_assets: bool) -> Result<BuildResult> {
|
||||||
let result = builder::build(config, true, skip_assets)?;
|
// Since web platform doesn't use `rust_flags`, this argument is explicitly
|
||||||
|
// set to `None`.
|
||||||
|
let result = builder::build(config, true, skip_assets, None)?;
|
||||||
// change the websocket reload state to true;
|
// change the websocket reload state to true;
|
||||||
// the page will auto-reload.
|
// the page will auto-reload.
|
||||||
if config.dioxus_config.web.watcher.reload_html {
|
if config.dioxus_config.web.watcher.reload_html {
|
||||||
|
|||||||
Reference in new issue
Block a user