소스 검색

pull out serve static assets methods

Evan Almloff 2 년 전
부모
커밋
fb6757484d

+ 2 - 6
packages/fullstack/examples/axum-router/src/main.rs

@@ -40,20 +40,16 @@ fn main() {
             .unwrap()
             .block_on(async move {
                 let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080));
-                use tower_http::services::ServeDir;
-
-                // Serve the dist/assets folder with the javascript and WASM files created by the CLI
-                let serve_dir = ServeDir::new("dist/assets");
 
                 axum::Server::bind(&addr)
                     .serve(
                         axum::Router::new()
+                            // Serve the dist/assets folder with the javascript and WASM files created by the CLI
+                            .serve_static_assets("./dist")
                             // Register server functions
                             .register_server_fns("")
                             // Connect to the hot reload server
                             .connect_hot_reload()
-                            // Serve the static assets folder
-                            .nest_service("/assets", serve_dir)
                             // If the path is unknown, render the application
                             .fallback(
                                 move |uri: http::uri::Uri, State(ssr_state): State<SSRState>| {

+ 1 - 2
packages/fullstack/server-macro/src/lib.rs

@@ -15,8 +15,7 @@ use server_fn_macro::*;
 ///   (e.g., `"/api"`). Defaults to `"/"`.
 /// 3. *Optional*: either `"Cbor"` (specifying that it should use the binary `cbor` format for
 ///   serialization), `"Url"` (specifying that it should be use a URL-encoded form-data string).
-///   Defaults to `"Url"`. If you want to use this server function to power a `<form>` that will
-///   work without WebAssembly, the encoding must be `"Url"`. If you want to use this server function
+///   Defaults to `"Url"`. If you want to use this server function
 ///   using Get instead of Post methods, the encoding must be `"GetCbor"` or `"GetJson"`.
 ///
 /// The server function itself can take any number of arguments, each of which should be serializable

+ 54 - 17
packages/fullstack/src/adapters/axum_adapter.rs

@@ -125,6 +125,7 @@ pub trait DioxusRouterExt<S> {
     ///     axum::Server::bind(&addr)
     ///         .serve(
     ///             axum::Router::new()
+    ///                 // Register server functions routes with the default handler
     ///                 .register_server_fns("")
     ///                 .into_make_service(),
     ///         )
@@ -148,7 +149,7 @@ pub trait DioxusRouterExt<S> {
     ///     axum::Server::bind(&addr)
     ///         .serve(
     ///             axum::Router::new()
-    ///                 // Server side render the application, serve static assets, and register server functions
+    ///                 // Connect to hot reloading in debug mode
     ///                 .connect_hot_reload()
     ///                 .into_make_service(),
     ///         )
@@ -158,6 +159,36 @@ pub trait DioxusRouterExt<S> {
     /// ```
     fn connect_hot_reload(self) -> Self;
 
+    /// Serves the static WASM for your Dioxus application (except the generated index.html).
+    ///
+    /// # Example
+    /// ```rust
+    /// #![allow(non_snake_case)]
+    /// use dioxus::prelude::*;
+    /// use dioxus_fullstack::prelude::*;
+    ///
+    /// #[tokio::main]
+    /// async fn main() {
+    ///     let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080));
+    ///     axum::Server::bind(&addr)
+    ///         .serve(
+    ///             axum::Router::new()
+    ///                 // Server side render the application, serve static assets, and register server functions
+    ///                 .serve_static_assets(ServeConfigBuilder::new(app, ()))
+    ///                 // Server render the application
+    ///                 // ...
+    ///                 .into_make_service(),
+    ///         )
+    ///         .await
+    ///         .unwrap();
+    /// }
+    ///
+    /// fn app(cx: Scope) -> Element {
+    ///     todo!()
+    /// }
+    /// ```
+    fn serve_static_assets(self, assets_path: impl Into<std::path::PathBuf>) -> Self;
+
     /// Serves the Dioxus application. This will serve a complete server side rendered application.
     /// This will serve static assets, server render the application, register server functions, and intigrate with hot reloading.
     ///
@@ -233,20 +264,16 @@ where
         })
     }
 
-    fn serve_dioxus_application<P: Clone + serde::Serialize + Send + Sync + 'static>(
-        mut self,
-        server_fn_route: &'static str,
-        cfg: impl Into<ServeConfig<P>>,
-    ) -> Self {
+    fn serve_static_assets(mut self, assets_path: impl Into<std::path::PathBuf>) -> Self {
         use tower_http::services::{ServeDir, ServeFile};
 
-        let cfg = cfg.into();
+        let assets_path = assets_path.into();
 
         // Serve all files in dist folder except index.html
-        let dir = std::fs::read_dir(cfg.assets_path).unwrap_or_else(|e| {
+        let dir = std::fs::read_dir(&assets_path).unwrap_or_else(|e| {
             panic!(
                 "Couldn't read assets directory at {:?}: {}",
-                &cfg.assets_path, e
+                &assets_path, e
             )
         });
 
@@ -256,7 +283,7 @@ where
                 continue;
             }
             let route = path
-                .strip_prefix(cfg.assets_path)
+                .strip_prefix(&assets_path)
                 .unwrap()
                 .iter()
                 .map(|segment| {
@@ -267,7 +294,6 @@ where
                 .collect::<Vec<_>>()
                 .join("/");
             let route = format!("/{}", route);
-            println!("Serving static asset at {}", route);
             if path.is_dir() {
                 self = self.nest_service(&route, ServeDir::new(path));
             } else {
@@ -275,13 +301,24 @@ where
             }
         }
 
+        self
+    }
+
+    fn serve_dioxus_application<P: Clone + serde::Serialize + Send + Sync + 'static>(
+        mut self,
+        server_fn_route: &'static str,
+        cfg: impl Into<ServeConfig<P>>,
+    ) -> Self {
+        let cfg = cfg.into();
+
         // Add server functions and render index.html
-        self.route(
-            "/",
-            get(render_handler).with_state((cfg, SSRState::default())),
-        )
-        .connect_hot_reload()
-        .register_server_fns(server_fn_route)
+        self.serve_static_assets(&cfg.assets_path)
+            .route(
+                "/",
+                get(render_handler).with_state((cfg, SSRState::default())),
+            )
+            .connect_hot_reload()
+            .register_server_fns(server_fn_route)
     }
 
     fn connect_hot_reload(self) -> Self {

+ 37 - 11
packages/fullstack/src/adapters/salvo_adapter.rs

@@ -153,6 +153,25 @@ pub trait DioxusRouterExt {
     /// }
     fn connect_hot_reload(self) -> Self;
 
+    /// Serves the static WASM for your Dioxus application (except the generated index.html).
+    ///
+    /// # Example
+    /// ```rust
+    /// use salvo::prelude::*;
+    /// use std::{net::TcpListener, sync::Arc};
+    /// use dioxus_fullstack::prelude::*;
+    ///
+    /// #[tokio::main]
+    /// async fn main() {
+    ///     let router = Router::new()
+    ///         .server_static_assets("/dist");
+    ///     Server::new(TcpListener::bind("127.0.0.1:8080"))
+    ///         .serve(router)
+    ///         .await;
+    /// }
+    /// ```
+    fn serve_static_assets(self, assets_path: impl Into<std::path::PathBuf>) -> Self;
+
     /// Serves the Dioxus application. This will serve a complete server side rendered application.
     /// This will serve static assets, server render the application, register server functions, and intigrate with hot reloading.
     ///
@@ -213,18 +232,14 @@ impl DioxusRouterExt for Router {
         })
     }
 
-    fn serve_dioxus_application<P: Clone + serde::Serialize + Send + Sync + 'static>(
-        mut self,
-        server_fn_route: &'static str,
-        cfg: impl Into<ServeConfig<P>>,
-    ) -> Self {
-        let cfg = cfg.into();
+    fn serve_static_assets(mut self, assets_path: impl Into<std::path::PathBuf>) -> Self {
+        let assets_path = assets_path.into();
 
         // Serve all files in dist folder except index.html
-        let dir = std::fs::read_dir(cfg.assets_path).unwrap_or_else(|e| {
+        let dir = std::fs::read_dir(&assets_path).unwrap_or_else(|e| {
             panic!(
                 "Couldn't read assets directory at {:?}: {}",
-                &cfg.assets_path, e
+                &assets_path, e
             )
         });
 
@@ -234,7 +249,7 @@ impl DioxusRouterExt for Router {
                 continue;
             }
             let route = path
-                .strip_prefix(&cfg.assets_path)
+                .strip_prefix(&assets_path)
                 .unwrap()
                 .iter()
                 .map(|segment| {
@@ -255,8 +270,19 @@ impl DioxusRouterExt for Router {
             }
         }
 
-        self.connect_hot_reload()
-            .register_server_fns(server_fn_route)
+        self
+    }
+
+    fn serve_dioxus_application<P: Clone + serde::Serialize + Send + Sync + 'static>(
+        self,
+        server_fn_path: &'static str,
+        cfg: impl Into<ServeConfig<P>>,
+    ) -> Self {
+        let cfg = cfg.into();
+
+        self.serve_static_assets(&cfg.assets_path)
+            .connect_hot_reload()
+            .register_server_fns(server_fn_path)
             .push(Router::with_path("/").get(SSRHandler { cfg }))
     }