mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 06:34:20 +00:00
Use Manganis Linker System (#2561)
* feat: new manganis linker * revision: fmt, clippy, cleanup * revision: link subcommand * fix: async runtime * revision: remove working dir arg * revision: switch dep source * fix: matrix, playwright * fix: fullstack manganis
This commit is contained in:
parent
90c46afd12
commit
2ef406982e
15 changed files with 332 additions and 172 deletions
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
|
@ -222,7 +222,7 @@ jobs:
|
|||
- {
|
||||
target: x86_64-pc-windows-msvc,
|
||||
os: windows-latest,
|
||||
toolchain: "1.75.0",
|
||||
toolchain: "1.76.0",
|
||||
cross: false,
|
||||
command: "test",
|
||||
args: "--all --tests",
|
||||
|
@ -230,7 +230,7 @@ jobs:
|
|||
- {
|
||||
target: x86_64-apple-darwin,
|
||||
os: macos-latest,
|
||||
toolchain: "1.75.0",
|
||||
toolchain: "1.76.0",
|
||||
cross: false,
|
||||
command: "test",
|
||||
args: "--all --tests",
|
||||
|
@ -238,7 +238,7 @@ jobs:
|
|||
- {
|
||||
target: aarch64-apple-ios,
|
||||
os: macos-latest,
|
||||
toolchain: "1.75.0",
|
||||
toolchain: "1.76.0",
|
||||
cross: false,
|
||||
command: "build",
|
||||
args: "--package dioxus-mobile",
|
||||
|
@ -246,7 +246,7 @@ jobs:
|
|||
- {
|
||||
target: aarch64-linux-android,
|
||||
os: ubuntu-latest,
|
||||
toolchain: "1.75.0",
|
||||
toolchain: "1.76.0",
|
||||
cross: true,
|
||||
command: "build",
|
||||
args: "--package dioxus-mobile",
|
||||
|
|
73
Cargo.lock
generated
73
Cargo.lock
generated
|
@ -906,7 +906,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"object 0.32.2",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
|
@ -1936,7 +1936,7 @@ dependencies = [
|
|||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa 1.0.11",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
|
@ -5918,8 +5918,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "manganis-cli-support"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d502b0db0ef8c880fecff174903815efedfacbcd5ea9a8bef96752f1e0d7eb6"
|
||||
source = "git+https://github.com/DogeDark/dioxus-collect-assets/#6b6077150c854af6497d8b96d3a070635ab9b6c4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo-lock",
|
||||
|
@ -5928,8 +5927,9 @@ dependencies = [
|
|||
"image 0.25.1",
|
||||
"imagequant",
|
||||
"lightningcss",
|
||||
"manganis-common",
|
||||
"manganis-common 0.2.4 (git+https://github.com/DogeDark/dioxus-collect-assets/)",
|
||||
"mozjpeg",
|
||||
"object 0.36.0",
|
||||
"petgraph",
|
||||
"png",
|
||||
"railwind",
|
||||
|
@ -5938,6 +5938,7 @@ dependencies = [
|
|||
"reqwest 0.11.27",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml 0.7.8",
|
||||
"tracing",
|
||||
"url",
|
||||
|
@ -5960,13 +5961,29 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "manganis-common"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/DogeDark/dioxus-collect-assets/#6b6077150c854af6497d8b96d3a070635ab9b6c4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
"home",
|
||||
"infer 0.11.0",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"toml 0.7.8",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "manganis-macro"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "704a0123ac90fa630b21a04fde56c29dfd5a7665c5e8f3639567989daa2d29d1"
|
||||
dependencies = [
|
||||
"manganis-common",
|
||||
"manganis-common 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
|
@ -6554,6 +6571,18 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
"wasmparser 0.208.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
|
@ -8117,6 +8146,17 @@ version = "1.0.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5174a470eeb535a721ae9fdd6e291c2411a906b96592182d05217591d5c5cf7b"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"derive_more",
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
|
@ -9899,6 +9939,16 @@ dependencies = [
|
|||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "1.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
|
@ -10132,7 +10182,7 @@ dependencies = [
|
|||
"log",
|
||||
"walrus-macro",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
"wasmparser 0.80.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -10419,6 +10469,15 @@ version = "0.80.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b"
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.208.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd921789c9dcc495f589cb37d200155dee65b4a4beeb853323b5e24e0a5f9c58"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.69"
|
||||
|
|
|
@ -98,7 +98,7 @@ wasm-bindgen-futures = "0.4.42"
|
|||
html_parser = "0.7.0"
|
||||
thiserror = "1.0.40"
|
||||
prettyplease = { version = "0.2.16", features = ["verbatim"] }
|
||||
manganis-cli-support = { version = "0.2.1", features = ["html"] }
|
||||
manganis-cli-support = { git = "https://github.com/DogeDark/dioxus-collect-assets/", features = ["html"] }
|
||||
manganis = { version = "0.2.1" }
|
||||
interprocess = { version = "1.2.2", package = "interprocess-docfix" }
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use brotli::enc::BrotliEncoderParams;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
use walkdir::WalkDir;
|
||||
|
@ -10,12 +11,16 @@ use dioxus_cli_config::CrateConfig;
|
|||
use dioxus_cli_config::Platform;
|
||||
use manganis_cli_support::{AssetManifest, AssetManifestExt};
|
||||
|
||||
pub fn asset_manifest(bin: Option<&str>, crate_config: &CrateConfig) -> AssetManifest {
|
||||
AssetManifest::load_from_path(
|
||||
bin,
|
||||
crate_config.crate_dir.join("Cargo.toml"),
|
||||
crate_config.workspace_dir.join("Cargo.lock"),
|
||||
)
|
||||
/// The temp file name for passing manganis json from linker to current exec.
|
||||
pub const MG_JSON_OUT: &str = "mg-out";
|
||||
|
||||
pub fn asset_manifest(config: &CrateConfig) -> AssetManifest {
|
||||
let file_path = config.out_dir().join(MG_JSON_OUT);
|
||||
let read = fs::read_to_string(&file_path).unwrap();
|
||||
_ = fs::remove_file(file_path);
|
||||
let json: Vec<String> = serde_json::from_str(&read).unwrap();
|
||||
|
||||
AssetManifest::load(json)
|
||||
}
|
||||
|
||||
/// Create a head file that contains all of the imports for assets that the user project uses
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
AssetConfigDropGuard,
|
||||
},
|
||||
error::{Error, Result},
|
||||
link::LinkCommand,
|
||||
tools::Tool,
|
||||
};
|
||||
use anyhow::Context;
|
||||
|
@ -83,13 +84,12 @@ pub fn build_web(
|
|||
let CrateConfig {
|
||||
crate_dir,
|
||||
target_dir,
|
||||
executable,
|
||||
dioxus_config,
|
||||
..
|
||||
} = config;
|
||||
let out_dir = config.out_dir();
|
||||
|
||||
let _guard = AssetConfigDropGuard::new();
|
||||
let _asset_guard = AssetConfigDropGuard::new();
|
||||
let _manganis_support = ManganisSupportGuard::default();
|
||||
|
||||
// start to build the assets
|
||||
|
@ -114,54 +114,76 @@ pub fn build_web(
|
|||
}
|
||||
}
|
||||
|
||||
let cmd = subprocess::Exec::cmd("cargo")
|
||||
let mut cargo_args = vec!["--target".to_string(), "wasm32-unknown-unknown".to_string()];
|
||||
|
||||
let mut cmd = subprocess::Exec::cmd("cargo")
|
||||
.set_rust_flags(rust_flags)
|
||||
.env("CARGO_TARGET_DIR", target_dir)
|
||||
.cwd(crate_dir)
|
||||
.arg("build")
|
||||
.arg("--target")
|
||||
.arg("wasm32-unknown-unknown")
|
||||
.arg("--message-format=json-render-diagnostics");
|
||||
|
||||
// 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 {
|
||||
cmd.arg("--release")
|
||||
if config.release {
|
||||
cargo_args.push("--release".to_string());
|
||||
}
|
||||
if config.verbose {
|
||||
cargo_args.push("--verbose".to_string());
|
||||
} else {
|
||||
cmd
|
||||
};
|
||||
let cmd = if config.verbose {
|
||||
cmd.arg("--verbose")
|
||||
} else {
|
||||
cmd.arg("--quiet")
|
||||
};
|
||||
cargo_args.push("--quiet".to_string());
|
||||
}
|
||||
|
||||
let cmd = if config.custom_profile.is_some() {
|
||||
if config.custom_profile.is_some() {
|
||||
let custom_profile = config.custom_profile.as_ref().unwrap();
|
||||
cmd.arg("--profile").arg(custom_profile)
|
||||
} else {
|
||||
cmd
|
||||
};
|
||||
cargo_args.push("--profile".to_string());
|
||||
cargo_args.push(custom_profile.to_string());
|
||||
}
|
||||
|
||||
let cmd = if config.features.is_some() {
|
||||
if config.features.is_some() {
|
||||
let features_str = config.features.as_ref().unwrap().join(" ");
|
||||
cmd.arg("--features").arg(features_str)
|
||||
} else {
|
||||
cmd
|
||||
};
|
||||
|
||||
let cmd = cmd.args(&config.cargo_args);
|
||||
|
||||
let cmd = match executable {
|
||||
ExecutableType::Binary(name) => cmd.arg("--bin").arg(name),
|
||||
ExecutableType::Lib(name) => cmd.arg("--lib").arg(name),
|
||||
ExecutableType::Example(name) => cmd.arg("--example").arg(name),
|
||||
cargo_args.push("--features".to_string());
|
||||
cargo_args.push(features_str);
|
||||
}
|
||||
|
||||
if let Some(target) = &config.target {
|
||||
cargo_args.push("--target".to_string());
|
||||
cargo_args.push(target.clone());
|
||||
}
|
||||
|
||||
cargo_args.append(&mut config.cargo_args.clone());
|
||||
|
||||
match &config.executable {
|
||||
ExecutableType::Binary(name) => {
|
||||
cargo_args.push("--bin".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
ExecutableType::Lib(name) => {
|
||||
cargo_args.push("--lib".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
ExecutableType::Example(name) => {
|
||||
cargo_args.push("--example".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
cmd = cmd.args(&cargo_args);
|
||||
let CargoBuildResult {
|
||||
warnings,
|
||||
output_location,
|
||||
} = prettier_build(cmd)?;
|
||||
|
||||
// Start Manganis linker intercept.
|
||||
let linker_args = vec![format!("{}", config.out_dir().display())];
|
||||
|
||||
manganis_cli_support::start_linker_intercept(
|
||||
&LinkCommand::command_name(),
|
||||
cargo_args,
|
||||
Some(linker_args),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let output_location = output_location.context("No output location found")?;
|
||||
|
||||
// [2] Establish the output directory structure
|
||||
|
@ -277,7 +299,7 @@ pub fn build_web(
|
|||
|
||||
let assets = if !skip_assets {
|
||||
tracing::info!("Processing assets");
|
||||
let assets = asset_manifest(executable.executable(), config);
|
||||
let assets = asset_manifest(config);
|
||||
process_assets(config, &assets)?;
|
||||
Some(assets)
|
||||
} else {
|
||||
|
@ -337,7 +359,9 @@ pub fn build_desktop(
|
|||
build_assets(config)?;
|
||||
let _guard = dioxus_cli_config::__private::save_config(config);
|
||||
let _manganis_support = ManganisSupportGuard::default();
|
||||
let _guard = AssetConfigDropGuard::new();
|
||||
let _asset_guard = AssetConfigDropGuard::new();
|
||||
|
||||
let mut cargo_args = Vec::new();
|
||||
|
||||
let mut cmd = subprocess::Exec::cmd("cargo")
|
||||
.set_rust_flags(rust_flags)
|
||||
|
@ -347,38 +371,60 @@ pub fn build_desktop(
|
|||
.arg("--message-format=json-render-diagnostics");
|
||||
|
||||
if config.release {
|
||||
cmd = cmd.arg("--release");
|
||||
cargo_args.push("--release".to_string());
|
||||
}
|
||||
if config.verbose {
|
||||
cmd = cmd.arg("--verbose");
|
||||
cargo_args.push("--verbose".to_string());
|
||||
} else {
|
||||
cmd = cmd.arg("--quiet");
|
||||
cargo_args.push("--quiet".to_string());
|
||||
}
|
||||
|
||||
if config.custom_profile.is_some() {
|
||||
let custom_profile = config.custom_profile.as_ref().unwrap();
|
||||
cmd = cmd.arg("--profile").arg(custom_profile);
|
||||
cargo_args.push("--profile".to_string());
|
||||
cargo_args.push(custom_profile.to_string());
|
||||
}
|
||||
|
||||
if config.features.is_some() {
|
||||
let features_str = config.features.as_ref().unwrap().join(" ");
|
||||
cmd = cmd.arg("--features").arg(features_str);
|
||||
cargo_args.push("--features".to_string());
|
||||
cargo_args.push(features_str);
|
||||
}
|
||||
|
||||
if let Some(target) = &config.target {
|
||||
cmd = cmd.arg("--target").arg(target);
|
||||
cargo_args.push("--target".to_string());
|
||||
cargo_args.push(target.clone());
|
||||
}
|
||||
|
||||
cmd = cmd.args(&config.cargo_args);
|
||||
cargo_args.append(&mut config.cargo_args.clone());
|
||||
|
||||
let cmd = match &config.executable {
|
||||
ExecutableType::Binary(name) => cmd.arg("--bin").arg(name),
|
||||
ExecutableType::Lib(name) => cmd.arg("--lib").arg(name),
|
||||
ExecutableType::Example(name) => cmd.arg("--example").arg(name),
|
||||
match &config.executable {
|
||||
ExecutableType::Binary(name) => {
|
||||
cargo_args.push("--bin".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
ExecutableType::Lib(name) => {
|
||||
cargo_args.push("--lib".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
ExecutableType::Example(name) => {
|
||||
cargo_args.push("--example".to_string());
|
||||
cargo_args.push(name.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
cmd = cmd.args(&cargo_args);
|
||||
let warning_messages = prettier_build(cmd)?;
|
||||
|
||||
// Start Manganis linker intercept.
|
||||
let linker_args = vec![format!("{}", config.out_dir().display())];
|
||||
|
||||
manganis_cli_support::start_linker_intercept(
|
||||
&LinkCommand::command_name(),
|
||||
cargo_args,
|
||||
Some(linker_args),
|
||||
)?;
|
||||
|
||||
let file_name: String = config.executable.executable().unwrap().to_string();
|
||||
|
||||
let target_file = if cfg!(windows) {
|
||||
|
@ -399,7 +445,7 @@ pub fn build_desktop(
|
|||
|
||||
let assets = if !skip_assets {
|
||||
tracing::info!("Processing assets");
|
||||
let assets = asset_manifest(config.executable.executable(), config);
|
||||
let assets = asset_manifest(config);
|
||||
// Collect assets
|
||||
process_assets(config, &assets)?;
|
||||
// Create the __assets_head.html file for bundling
|
||||
|
|
|
@ -16,22 +16,26 @@ pub struct Check {
|
|||
|
||||
impl Check {
|
||||
// Todo: check the entire crate
|
||||
pub async fn check(self) -> Result<()> {
|
||||
match self.file {
|
||||
// Default to checking the project
|
||||
None => {
|
||||
if let Err(e) = check_project_and_report().await {
|
||||
eprintln!("error checking project: {}", e);
|
||||
exit(1);
|
||||
pub fn check(self) -> Result<()> {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async move {
|
||||
match self.file {
|
||||
// Default to checking the project
|
||||
None => {
|
||||
if let Err(e) = check_project_and_report().await {
|
||||
eprintln!("error checking project: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Some(file) => {
|
||||
if let Err(e) = check_file_and_report(file).await {
|
||||
eprintln!("failed to check file: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(file) => {
|
||||
if let Err(e) = check_file_and_report(file).await {
|
||||
eprintln!("failed to check file: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
39
packages/cli/src/cli/link.rs
Normal file
39
packages/cli/src/cli/link.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::{assets, error::Result};
|
||||
use clap::Parser;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
#[derive(Clone, Debug, Parser)]
|
||||
#[clap(name = "link", hide = true)]
|
||||
pub struct LinkCommand {
|
||||
// Allow us to accept any argument after `dx link`
|
||||
#[clap(trailing_var_arg = true, allow_hyphen_values = true)]
|
||||
pub args: Vec<String>,
|
||||
}
|
||||
|
||||
impl LinkCommand {
|
||||
pub fn link(self) -> Result<()> {
|
||||
let Some((link_args, object_files)) = manganis_cli_support::linker_intercept(self.args)
|
||||
else {
|
||||
tracing::warn!("Invalid linker arguments.");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Parse object files, deserialize JSON, & create a file to propogate JSON.
|
||||
let json = manganis_cli_support::get_json_from_object_files(object_files);
|
||||
let parsed = serde_json::to_string(&json).unwrap();
|
||||
|
||||
let out_dir = PathBuf::from(link_args.first().unwrap());
|
||||
fs::create_dir_all(&out_dir).unwrap();
|
||||
|
||||
let path = out_dir.join(assets::MG_JSON_OUT);
|
||||
fs::write(path, parsed).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// We need to pass the subcommand name to Manganis so this
|
||||
/// helps centralize where we set the subcommand "name".
|
||||
pub fn command_name() -> String {
|
||||
"link".to_string()
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ pub mod clean;
|
|||
pub mod config;
|
||||
pub mod create;
|
||||
pub mod init;
|
||||
pub mod link;
|
||||
pub mod plugin;
|
||||
pub mod serve;
|
||||
pub mod translate;
|
||||
|
@ -85,6 +86,10 @@ pub enum Commands {
|
|||
#[cfg(feature = "plugin")]
|
||||
#[clap(subcommand)]
|
||||
Plugin(plugin::Plugin),
|
||||
|
||||
/// Handles parsing of linker arguments for linker-based systems
|
||||
/// such as Manganis and binary patching.
|
||||
Link(link::LinkCommand),
|
||||
}
|
||||
|
||||
impl Display for Commands {
|
||||
|
@ -100,6 +105,7 @@ impl Display for Commands {
|
|||
Commands::Autoformat(_) => write!(f, "fmt"),
|
||||
Commands::Check(_) => write!(f, "check"),
|
||||
Commands::Bundle(_) => write!(f, "bundle"),
|
||||
Commands::Link(_) => write!(f, "link"),
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
Commands::Plugin(_) => write!(f, "plugin"),
|
||||
|
|
|
@ -15,7 +15,7 @@ pub enum Plugin {
|
|||
}
|
||||
|
||||
impl Plugin {
|
||||
pub async fn plugin(self) -> Result<()> {
|
||||
pub fn plugin(self) -> Result<()> {
|
||||
match self {
|
||||
Plugin::List {} => {
|
||||
for item in crate::plugin::PluginManager::plugin_list() {
|
||||
|
|
|
@ -14,7 +14,7 @@ pub struct Serve {
|
|||
}
|
||||
|
||||
impl Serve {
|
||||
pub async fn serve(self, bin: Option<PathBuf>) -> Result<()> {
|
||||
pub fn serve(self, bin: Option<PathBuf>) -> Result<()> {
|
||||
let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?;
|
||||
let serve_cfg = self.serve.clone();
|
||||
|
||||
|
@ -65,10 +65,10 @@ impl Serve {
|
|||
// start the develop server
|
||||
use server::{desktop, fullstack, web};
|
||||
match platform {
|
||||
Platform::Web => web::startup(crate_config.clone(), &serve_cfg).await?,
|
||||
Platform::Desktop => desktop::startup(crate_config.clone(), &serve_cfg).await?,
|
||||
Platform::Web => web::startup(crate_config.clone(), &serve_cfg)?,
|
||||
Platform::Desktop => desktop::startup(crate_config.clone(), &serve_cfg)?,
|
||||
Platform::Fullstack | Platform::StaticGeneration => {
|
||||
fullstack::startup(crate_config.clone(), &serve_cfg).await?
|
||||
fullstack::startup(crate_config.clone(), &serve_cfg)?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
|
||||
mod assets;
|
||||
pub mod assets;
|
||||
pub mod builder;
|
||||
pub mod server;
|
||||
pub mod tools;
|
||||
|
|
|
@ -10,8 +10,7 @@ use Commands::*;
|
|||
|
||||
const LOG_ENV: &str = "DIOXUS_LOG";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let args = Cli::parse();
|
||||
|
||||
// If {LOG_ENV} is set, default to env, otherwise filter to cli
|
||||
|
@ -40,19 +39,17 @@ async fn main() -> anyhow::Result<()> {
|
|||
.context(error_wrapper("Configuring new project failed")),
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
Plugin(opts) => opts
|
||||
.plugin()
|
||||
.await
|
||||
.context(error_wrapper("Error with plugin")),
|
||||
Plugin(opts) => opts.plugin().context(error_wrapper("Error with plugin")),
|
||||
|
||||
Autoformat(opts) => opts
|
||||
.autoformat()
|
||||
.context(error_wrapper("Error autoformatting RSX")),
|
||||
|
||||
Check(opts) => opts
|
||||
.check()
|
||||
.await
|
||||
.context(error_wrapper("Error checking RSX")),
|
||||
Check(opts) => opts.check().context(error_wrapper("Error checking RSX")),
|
||||
|
||||
Link(opts) => opts
|
||||
.link()
|
||||
.context(error_wrapper("Error with linker passthrough")),
|
||||
|
||||
action => {
|
||||
let bin = get_bin(args.bin)?;
|
||||
|
@ -81,7 +78,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
Serve(opts) => opts
|
||||
.serve(Some(bin.clone()))
|
||||
.await
|
||||
.context(error_wrapper("Serving project failed")),
|
||||
|
||||
Bundle(opts) => opts
|
||||
|
|
|
@ -23,11 +23,11 @@ use crate::plugin::PluginManager;
|
|||
|
||||
use super::HotReloadState;
|
||||
|
||||
pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
||||
startup_with_platform::<DesktopPlatform>(config, serve).await
|
||||
pub fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
||||
startup_with_platform::<DesktopPlatform>(config, serve)
|
||||
}
|
||||
|
||||
pub(crate) async fn startup_with_platform<P: Platform + Send + 'static>(
|
||||
pub(crate) fn startup_with_platform<P: Platform + Send + 'static>(
|
||||
config: CrateConfig,
|
||||
serve_cfg: &ConfigOptsServe,
|
||||
) -> Result<()> {
|
||||
|
@ -54,7 +54,7 @@ pub(crate) async fn startup_with_platform<P: Platform + Send + 'static>(
|
|||
file_map,
|
||||
};
|
||||
|
||||
serve::<P>(config, serve_cfg, hot_reload_state).await?;
|
||||
serve::<P>(config, serve_cfg, hot_reload_state)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -70,53 +70,55 @@ fn set_ctrl_c(config: &CrateConfig) {
|
|||
}
|
||||
|
||||
/// Start the server without hot reload
|
||||
async fn serve<P: Platform + Send + 'static>(
|
||||
fn serve<P: Platform + Send + 'static>(
|
||||
config: CrateConfig,
|
||||
serve: &ConfigOptsServe,
|
||||
hot_reload_state: HotReloadState,
|
||||
) -> Result<()> {
|
||||
let hot_reload: tokio::task::JoinHandle<Result<()>> = tokio::spawn({
|
||||
let hot_reload_state = hot_reload_state.clone();
|
||||
async move {
|
||||
match hot_reload_state.file_map.clone() {
|
||||
Some(file_map) => {
|
||||
// The open interprocess sockets
|
||||
start_desktop_hot_reload(hot_reload_state, file_map).await?;
|
||||
}
|
||||
None => {
|
||||
std::future::pending::<()>().await;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
});
|
||||
|
||||
let platform = RwLock::new(P::start(&config, serve, Vec::new())?);
|
||||
|
||||
tracing::info!("🚀 Starting development server...");
|
||||
|
||||
// We got to own watcher so that it exists for the duration of serve
|
||||
// Otherwise full reload won't work.
|
||||
let _watcher = setup_file_watcher(
|
||||
{
|
||||
let config = config.clone();
|
||||
let serve = serve.clone();
|
||||
move || {
|
||||
platform
|
||||
.write()
|
||||
.unwrap()
|
||||
.rebuild(&config, &serve, Vec::new())
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async move {
|
||||
let hot_reload: tokio::task::JoinHandle<Result<()>> = tokio::spawn({
|
||||
let hot_reload_state = hot_reload_state.clone();
|
||||
async move {
|
||||
match hot_reload_state.file_map.clone() {
|
||||
Some(file_map) => {
|
||||
// The open interprocess sockets
|
||||
start_desktop_hot_reload(hot_reload_state, file_map).await?;
|
||||
}
|
||||
None => {
|
||||
std::future::pending::<()>().await;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
&config,
|
||||
None,
|
||||
hot_reload_state,
|
||||
)
|
||||
.await?;
|
||||
});
|
||||
|
||||
hot_reload.await.unwrap()?;
|
||||
tracing::info!("🚀 Starting development server...");
|
||||
|
||||
Ok(())
|
||||
// We got to own watcher so that it exists for the duration of serve
|
||||
// Otherwise full reload won't work.
|
||||
let _watcher = setup_file_watcher(
|
||||
{
|
||||
let config = config.clone();
|
||||
let serve = serve.clone();
|
||||
move || {
|
||||
platform
|
||||
.write()
|
||||
.unwrap()
|
||||
.rebuild(&config, &serve, Vec::new())
|
||||
}
|
||||
},
|
||||
&config,
|
||||
None,
|
||||
hot_reload_state,
|
||||
)
|
||||
.await?;
|
||||
|
||||
hot_reload.await.unwrap()?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_desktop_hot_reload(
|
||||
|
|
|
@ -36,8 +36,8 @@ pub fn server_rust_flags(build: &ConfigOptsBuild) -> String {
|
|||
rust_flags(build, SERVER_RUST_FLAGS)
|
||||
}
|
||||
|
||||
pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
||||
desktop::startup_with_platform::<FullstackPlatform>(config, serve).await
|
||||
pub fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
|
||||
desktop::startup_with_platform::<FullstackPlatform>(config, serve)
|
||||
}
|
||||
|
||||
fn start_web_build_thread(
|
||||
|
|
|
@ -22,7 +22,7 @@ use server::*;
|
|||
|
||||
use super::HotReloadState;
|
||||
|
||||
pub async fn startup(config: CrateConfig, serve_cfg: &ConfigOptsServe) -> Result<()> {
|
||||
pub fn startup(config: CrateConfig, serve_cfg: &ConfigOptsServe) -> Result<()> {
|
||||
set_ctrlc_handler(&config);
|
||||
|
||||
let ip = serve_cfg
|
||||
|
@ -33,11 +33,11 @@ pub async fn startup(config: CrateConfig, serve_cfg: &ConfigOptsServe) -> Result
|
|||
|
||||
let hot_reload_state = build_hotreload_filemap(&config);
|
||||
|
||||
serve(ip, config, hot_reload_state, serve_cfg).await
|
||||
serve(ip, config, hot_reload_state, serve_cfg)
|
||||
}
|
||||
|
||||
/// Start the server without hot reload
|
||||
pub async fn serve(
|
||||
pub fn serve(
|
||||
ip: IpAddr,
|
||||
config: CrateConfig,
|
||||
hot_reload_state: HotReloadState,
|
||||
|
@ -55,42 +55,45 @@ pub async fn serve(
|
|||
|
||||
tracing::info!("🚀 Starting development server...");
|
||||
|
||||
// We got to own watcher so that it exists for the duration of serve
|
||||
// Otherwise full reload won't work.
|
||||
let _watcher = setup_file_watcher(
|
||||
{
|
||||
let config = config.clone();
|
||||
let hot_reload_state = hot_reload_state.clone();
|
||||
move || build(&config, &hot_reload_state, skip_assets)
|
||||
},
|
||||
&config,
|
||||
Some(WebServerInfo { ip, port }),
|
||||
hot_reload_state.clone(),
|
||||
)
|
||||
.await?;
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async move {
|
||||
// We got to own watcher so that it exists for the duration of serve
|
||||
// Otherwise full reload won't work.
|
||||
let _watcher = setup_file_watcher(
|
||||
{
|
||||
let config = config.clone();
|
||||
let hot_reload_state = hot_reload_state.clone();
|
||||
move || build(&config, &hot_reload_state, skip_assets)
|
||||
},
|
||||
&config,
|
||||
Some(WebServerInfo { ip, port }),
|
||||
hot_reload_state.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// HTTPS
|
||||
// Before console info so it can stop if mkcert isn't installed or fails
|
||||
let rustls_config = get_rustls(&config).await?;
|
||||
// HTTPS
|
||||
// Before console info so it can stop if mkcert isn't installed or fails
|
||||
let rustls_config = get_rustls(&config).await?;
|
||||
|
||||
// Print serve info
|
||||
print_console_info(
|
||||
&config,
|
||||
PrettierOptions {
|
||||
changed: vec![],
|
||||
warnings: first_build_result.warnings,
|
||||
elapsed_time: first_build_result.elapsed_time,
|
||||
},
|
||||
Some(WebServerInfo { ip, port }),
|
||||
);
|
||||
// Print serve info
|
||||
print_console_info(
|
||||
&config,
|
||||
PrettierOptions {
|
||||
changed: vec![],
|
||||
warnings: first_build_result.warnings,
|
||||
elapsed_time: first_build_result.elapsed_time,
|
||||
},
|
||||
Some(WebServerInfo { ip, port }),
|
||||
);
|
||||
|
||||
// Router
|
||||
let router = setup_router(config.clone(), hot_reload_state).await?;
|
||||
// Router
|
||||
let router = setup_router(config.clone(), hot_reload_state).await?;
|
||||
|
||||
// Start server
|
||||
start_server(ip, port, router, opts.open, rustls_config, &config).await?;
|
||||
// Start server
|
||||
start_server(ip, port, router, opts.open, rustls_config, &config).await?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Starts dx serve with no hot reload
|
||||
|
|
Loading…
Reference in a new issue