Simplify the launch builder (#2967)

* improve documentation for the fullstack server context

* Add a section about axum integration to the crate root docs

* make serve_dioxus_application accept the cfg builder directly

* remove unused server_fn module

* improve fullstack config docs

* improve documentation for the server function macro

* fix axum router extension link

* Fix doc tests

* Fix launch builder

* Simplify the launch builder

* don't re-export launch in the prelude

* refactor fullstack launch

* Fix fullstack launch builder

* Update static generation with the new builder api

* fix some formatting/overly broad launch replacements

* fix custom menu example

* fix fullstack/static generation examples

* Fix static generation launch

* A few small formatting fixes

* Fix a few doc tests

* implement LaunchConfig for serve configs

* fix fullstack launch with separate web and server launch methods

* fix check with all features

* dont expose inner core module

* clippy and check

* fix readme

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2024-10-10 16:00:58 -07:00
1 parent 2d7bef44e8
commit 20d146d9bd
126 files changed
+618 -989

No files matched your search

+10 -16
View File
@@ -1,6 +1,7 @@
use std::future::{poll_fn, Future, IntoFuture};
use std::task::Poll;
use crate::builder::OpenArguments;
use crate::cli::serve::Serve;
use crate::dioxus_crate::DioxusCrate;
use crate::tracer::CLILogControl;
@@ -156,23 +157,14 @@ pub async fn serve_all(
builder.children.clear();
}
let asset_dir = dioxus_crate
.dioxus_config
.application
.asset_dir
.canonicalize()
.unwrap_or(std::path::PathBuf::from("./assets"));
// If we have a build result, open it
for build_result in results.iter() {
let child = build_result.open(
OpenArguments::new(
&serve.server_arguments,
server.fullstack_address(),
&dioxus_crate.workspace_dir(),
&asset_dir,
server.ip,
dioxus_crate.dioxus_config.application.name.clone(),
dioxus_crate.out_dir()
&dioxus_crate
)
);
match child {
Ok(Some(child_proc)) => builder.children.push((build_result.target_platform, child_proc)),
@@ -192,12 +184,12 @@ pub async fn serve_all(
server.send_reload_command().await;
},
// If the process exited *cleanly*, we can exit
// If the desktop process exited *cleanly*, we can exit
Ok(BuilderUpdate::ProcessExited { status, target_platform }) => {
// Then remove the child process
builder.children.retain(|(platform, _)| *platform != target_platform);
match status {
Ok(status) => {
match (target_platform, status) {
(TargetPlatform::Desktop, Ok(status)) => {
if status.success() {
break;
}
@@ -205,7 +197,9 @@ pub async fn serve_all(
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with status: {status}");
}
},
Err(e) => {
// Ignore the static generation platform exiting
(_ , Ok(_)) => {},
(_, Err(e)) => {
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with error: {e}");
}
}
+27 -8
View File
@@ -114,7 +114,7 @@ impl Server {
// If we're serving a fullstack app, we need to find a port to proxy to
let fullstack_port = if matches!(
serve.build_arguments.platform(),
Platform::Liveview | Platform::Fullstack | Platform::StaticGeneration
Platform::Liveview | Platform::Fullstack
) {
get_available_port(addr.ip())
} else {
@@ -368,7 +368,7 @@ fn setup_router(
// server the dir if it's web, otherwise let the fullstack server itself handle it
match platform {
Platform::Web => {
Platform::Web | Platform::StaticGeneration => {
// Route file service to output the .wasm and assets if this is a web build
let base_path = format!(
"/{}",
@@ -382,9 +382,9 @@ fn setup_router(
.trim_matches('/')
);
router = router.nest_service(&base_path, build_serve_dir(serve, config));
router = router.nest_service(&base_path, build_serve_dir(serve, config, platform));
}
Platform::Liveview | Platform::Fullstack | Platform::StaticGeneration => {
Platform::Liveview | Platform::Fullstack => {
// For fullstack and static generation, forward all requests to the server
let address = fullstack_address.unwrap();
@@ -449,7 +449,11 @@ fn setup_router(
Ok(router)
}
fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRouter {
fn build_serve_dir(
serve: &Serve,
cfg: &DioxusCrate,
platform: Platform,
) -> axum::routing::MethodRouter {
static CORS_UNSAFE: (HeaderValue, HeaderValue) = (
HeaderValue::from_static("unsafe-none"),
HeaderValue::from_static("unsafe-none"),
@@ -465,7 +469,11 @@ fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRou
false => CORS_UNSAFE.clone(),
};
let out_dir = cfg.out_dir();
let out_dir = match platform {
// Static generation only serves files from the public directory
Platform::StaticGeneration => cfg.out_dir().join("public"),
_ => cfg.out_dir(),
};
let index_on_404 = cfg.dioxus_config.web.watcher.index_on_404;
get_service(
@@ -479,7 +487,7 @@ fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRou
let out_dir = out_dir.clone();
move |response| async move { Ok(no_cache(index_on_404, &out_dir, response)) }
})
.service(ServeDir::new(out_dir)),
.service(ServeDir::new(&out_dir)),
)
.handle_error(|error: Infallible| async move {
(
@@ -500,7 +508,18 @@ fn no_cache(
// If there's a 404 and we're supposed to index on 404, upgrade that failed request to the index.html
// We might want to isnert a header here saying we *did* that but oh well
if response.status() == StatusCode::NOT_FOUND && index_on_404 {
let body = Body::from(std::fs::read_to_string(out_dir.join("index.html")).unwrap());
// First try to find a 404.html or 404/index.html file
let out_dir_404_html = out_dir.join("404.html");
let out_dir_404_index_html = out_dir.join("404").join("index.html");
let path = if out_dir_404_html.exists() {
out_dir_404_html
} else if out_dir_404_index_html.exists() {
out_dir_404_index_html
} else {
// If we can't find a 404.html or 404/index.html, just use the index.html
out_dir.join("index.html")
};
let body = Body::from(std::fs::read_to_string(path).unwrap());
response = Response::builder()
.status(StatusCode::OK)