1
0

config.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //! Launch helper macros for fullstack apps
  2. #![allow(unused)]
  3. use crate::prelude::*;
  4. use dioxus_lib::prelude::{dioxus_core::AnyProps, *};
  5. use std::sync::Arc;
  6. /// Settings for a fullstack app.
  7. pub struct Config {
  8. #[cfg(feature = "ssr")]
  9. pub(crate) server_fn_route: &'static str,
  10. #[cfg(feature = "ssr")]
  11. pub(crate) server_cfg: ServeConfigBuilder,
  12. #[cfg(feature = "ssr")]
  13. pub(crate) addr: std::net::SocketAddr,
  14. #[cfg(feature = "web")]
  15. pub(crate) web_cfg: dioxus_web::Config,
  16. #[cfg(feature = "desktop")]
  17. pub(crate) desktop_cfg: dioxus_desktop::Config,
  18. }
  19. #[allow(clippy::derivable_impls)]
  20. impl Default for Config {
  21. fn default() -> Self {
  22. Self {
  23. #[cfg(feature = "ssr")]
  24. server_fn_route: "",
  25. #[cfg(feature = "ssr")]
  26. addr: std::net::SocketAddr::from(([127, 0, 0, 1], 8080)),
  27. #[cfg(feature = "ssr")]
  28. server_cfg: ServeConfigBuilder::new(),
  29. #[cfg(feature = "web")]
  30. web_cfg: dioxus_web::Config::default(),
  31. #[cfg(feature = "desktop")]
  32. desktop_cfg: dioxus_desktop::Config::default(),
  33. }
  34. }
  35. }
  36. impl Config {
  37. /// Create a new config for a fullstack app.
  38. pub fn new() -> Self {
  39. Self::default()
  40. }
  41. /// Set the address to serve the app on.
  42. #[cfg(feature = "ssr")]
  43. pub fn addr(self, addr: impl Into<std::net::SocketAddr>) -> Self {
  44. let addr = addr.into();
  45. Self { addr, ..self }
  46. }
  47. /// Set the route to the server functions.
  48. #[cfg(feature = "ssr")]
  49. pub fn server_fn_route(self, server_fn_route: &'static str) -> Self {
  50. Self {
  51. server_fn_route,
  52. ..self
  53. }
  54. }
  55. /// Set the incremental renderer config.
  56. #[cfg(feature = "ssr")]
  57. pub fn incremental(self, cfg: IncrementalRendererConfig) -> Self {
  58. Self {
  59. server_cfg: self.server_cfg.incremental(cfg),
  60. ..self
  61. }
  62. }
  63. /// Set the server config.
  64. #[cfg(feature = "ssr")]
  65. pub fn server_cfg(self, server_cfg: ServeConfigBuilder) -> Self {
  66. Self { server_cfg, ..self }
  67. }
  68. /// Set the web config.
  69. #[cfg(feature = "web")]
  70. pub fn web_cfg(self, web_cfg: dioxus_web::Config) -> Self {
  71. Self { web_cfg, ..self }
  72. }
  73. /// Set the desktop config.
  74. #[cfg(feature = "desktop")]
  75. pub fn desktop_cfg(self, desktop_cfg: dioxus_desktop::Config) -> Self {
  76. Self {
  77. desktop_cfg,
  78. ..self
  79. }
  80. }
  81. #[cfg(feature = "ssr")]
  82. /// Launch a server application
  83. pub async fn launch_server(
  84. self,
  85. build_virtual_dom: impl Fn() -> VirtualDom + Send + Sync + 'static,
  86. ) {
  87. let addr = self.addr;
  88. println!("Listening on {}", addr);
  89. let cfg = self.server_cfg.build();
  90. let server_fn_route = self.server_fn_route;
  91. #[cfg(all(feature = "axum", not(feature = "warp"), not(feature = "salvo")))]
  92. {
  93. use crate::adapters::axum_adapter::{render_handler, DioxusRouterExt};
  94. use axum::routing::get;
  95. use tower::ServiceBuilder;
  96. let ssr_state = SSRState::new(&cfg);
  97. let router = axum::Router::new().register_server_fns(server_fn_route);
  98. #[cfg(not(feature = "desktop"))]
  99. let router = router
  100. .serve_static_assets(cfg.assets_path)
  101. .connect_hot_reload()
  102. .fallback(get(render_handler).with_state((
  103. cfg,
  104. Arc::new(build_virtual_dom),
  105. ssr_state,
  106. )));
  107. let router = router
  108. .layer(
  109. ServiceBuilder::new()
  110. .layer(tower_http::compression::CompressionLayer::new().gzip(true)),
  111. )
  112. .into_make_service();
  113. axum::Server::bind(&addr).serve(router).await.unwrap();
  114. }
  115. #[cfg(all(feature = "warp", not(feature = "axum"), not(feature = "salvo")))]
  116. {
  117. use warp::Filter;
  118. // First register the server functions
  119. let router = register_server_fns(server_fn_route);
  120. #[cfg(not(feature = "desktop"))]
  121. let router = {
  122. // Serve the dist folder and the index.html file
  123. let serve_dir = warp::fs::dir(cfg.assets_path);
  124. let build_virtual_dom = Arc::new(build_virtual_dom);
  125. router
  126. .or(connect_hot_reload())
  127. // Then the index route
  128. .or(warp::path::end().and(render_ssr(cfg.clone(), {
  129. let build_virtual_dom = build_virtual_dom.clone();
  130. move || build_virtual_dom()
  131. })))
  132. // Then the static assets
  133. .or(serve_dir)
  134. // Then all other routes
  135. .or(render_ssr(cfg, move || build_virtual_dom()))
  136. };
  137. warp::serve(router.boxed().with(warp::filters::compression::gzip()))
  138. .run(addr)
  139. .await;
  140. }
  141. #[cfg(all(feature = "salvo", not(feature = "axum"), not(feature = "warp")))]
  142. {
  143. use crate::adapters::salvo_adapter::{DioxusRouterExt, SSRHandler};
  144. use salvo::conn::Listener;
  145. let router = salvo::Router::new().register_server_fns(server_fn_route);
  146. #[cfg(not(feature = "desktop"))]
  147. let router = router
  148. .serve_static_assets(cfg.assets_path)
  149. .connect_hot_reload()
  150. .push(salvo::Router::with_path("/<**any_path>").get(SSRHandler::new(cfg)));
  151. let router = router.hoop(
  152. salvo::compression::Compression::new()
  153. .enable_gzip(salvo::prelude::CompressionLevel::Default),
  154. );
  155. salvo::Server::new(salvo::conn::tcp::TcpListener::new(addr).bind().await)
  156. .serve(router)
  157. .await;
  158. }
  159. }
  160. }