mod.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. use crate::{
  2. cfg::{ConfigOptsBuild, ConfigOptsServe},
  3. CrateConfig, Result, WebAssetConfigDropGuard,
  4. };
  5. use super::{desktop, Platform};
  6. pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
  7. desktop::startup_with_platform::<FullstackPlatform>(config, serve).await
  8. }
  9. fn start_web_build_thread(
  10. config: &CrateConfig,
  11. serve: &ConfigOptsServe,
  12. ) -> std::thread::JoinHandle<Result<()>> {
  13. let serve = serve.clone();
  14. let target_directory = config.crate_dir.join(".dioxus").join("web");
  15. std::fs::create_dir_all(&target_directory).unwrap();
  16. std::thread::spawn(move || build_web(serve, &target_directory))
  17. }
  18. struct FullstackPlatform {
  19. serve: ConfigOptsServe,
  20. desktop: desktop::DesktopPlatform,
  21. _config: WebAssetConfigDropGuard,
  22. }
  23. impl Platform for FullstackPlatform {
  24. fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result<Self>
  25. where
  26. Self: Sized,
  27. {
  28. let thread_handle = start_web_build_thread(config, serve);
  29. let mut desktop_config = config.clone();
  30. let desktop_feature = serve.server_feature.clone();
  31. let features = &mut desktop_config.features;
  32. match features {
  33. Some(features) => {
  34. features.push(desktop_feature);
  35. }
  36. None => desktop_config.features = Some(vec![desktop_feature]),
  37. };
  38. let config = WebAssetConfigDropGuard::new();
  39. let desktop = desktop::DesktopPlatform::start(&desktop_config, serve)?;
  40. thread_handle
  41. .join()
  42. .map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
  43. Ok(Self {
  44. desktop,
  45. serve: serve.clone(),
  46. _config: config,
  47. })
  48. }
  49. fn rebuild(&mut self, crate_config: &CrateConfig) -> Result<crate::BuildResult> {
  50. let thread_handle = start_web_build_thread(crate_config, &self.serve);
  51. let result = {
  52. let mut desktop_config = crate_config.clone();
  53. let desktop_feature = self.serve.server_feature.clone();
  54. let features = &mut desktop_config.features;
  55. match features {
  56. Some(features) => {
  57. features.push(desktop_feature);
  58. }
  59. None => desktop_config.features = Some(vec![desktop_feature]),
  60. };
  61. let _gaurd = FullstackServerEnvGuard::new(self.serve.force_debug, self.serve.release);
  62. self.desktop.rebuild(&desktop_config)
  63. };
  64. thread_handle
  65. .join()
  66. .map_err(|_| anyhow::anyhow!("Failed to join thread"))??;
  67. result
  68. }
  69. }
  70. fn build_web(serve: ConfigOptsServe, target_directory: &std::path::Path) -> Result<()> {
  71. let mut web_config: ConfigOptsBuild = serve.into();
  72. let web_feature = web_config.client_feature.clone();
  73. let features = &mut web_config.features;
  74. match features {
  75. Some(features) => {
  76. features.push(web_feature);
  77. }
  78. None => web_config.features = Some(vec![web_feature]),
  79. };
  80. web_config.platform = Some(crate::cfg::Platform::Web);
  81. let _gaurd = FullstackWebEnvGuard::new(&web_config);
  82. crate::cli::build::Build { build: web_config }.build(None, Some(target_directory))
  83. }
  84. // 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
  85. // This reduces a hello world from ~40MB to ~2MB
  86. pub(crate) struct FullstackWebEnvGuard {
  87. old_rustflags: Option<String>,
  88. }
  89. impl FullstackWebEnvGuard {
  90. pub fn new(serve: &ConfigOptsBuild) -> Self {
  91. Self {
  92. old_rustflags: (!serve.force_debug).then(|| {
  93. let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default();
  94. let debug_assertions = if serve.release {
  95. ""
  96. } else {
  97. " -C debug-assertions"
  98. };
  99. std::env::set_var(
  100. "RUSTFLAGS",
  101. format!(
  102. "{old_rustflags} -C debuginfo=none -C strip=debuginfo{debug_assertions}"
  103. ),
  104. );
  105. old_rustflags
  106. }),
  107. }
  108. }
  109. }
  110. impl Drop for FullstackWebEnvGuard {
  111. fn drop(&mut self) {
  112. if let Some(old_rustflags) = self.old_rustflags.take() {
  113. std::env::set_var("RUSTFLAGS", old_rustflags);
  114. }
  115. }
  116. }
  117. // 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
  118. // This reduces a hello world from ~40MB to ~2MB
  119. pub(crate) struct FullstackServerEnvGuard {
  120. old_rustflags: Option<String>,
  121. }
  122. impl FullstackServerEnvGuard {
  123. pub fn new(debug: bool, release: bool) -> Self {
  124. Self {
  125. old_rustflags: (!debug).then(|| {
  126. let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default();
  127. let debug_assertions = if release { "" } else { " -C debug-assertions" };
  128. std::env::set_var(
  129. "RUSTFLAGS",
  130. format!("{old_rustflags} -C opt-level=2 {debug_assertions}"),
  131. );
  132. old_rustflags
  133. }),
  134. }
  135. }
  136. }
  137. impl Drop for FullstackServerEnvGuard {
  138. fn drop(&mut self) {
  139. if let Some(old_rustflags) = self.old_rustflags.take() {
  140. std::env::set_var("RUSTFLAGS", old_rustflags);
  141. }
  142. }
  143. }