mod.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. use crate::{BuildResult, CrateConfig, Result};
  2. use cargo_metadata::diagnostic::Diagnostic;
  3. use dioxus_core::Template;
  4. use dioxus_html::HtmlCtx;
  5. use dioxus_rsx::hot_reload::*;
  6. use notify::{RecommendedWatcher, Watcher};
  7. use std::{
  8. path::PathBuf,
  9. sync::{Arc, Mutex},
  10. };
  11. use tokio::sync::broadcast::{self};
  12. mod output;
  13. use output::*;
  14. pub mod desktop;
  15. pub mod web;
  16. /// Sets up a file watcher
  17. async fn setup_file_watcher<F: Fn() -> Result<BuildResult> + Send + 'static>(
  18. build_with: F,
  19. config: &CrateConfig,
  20. web_info: Option<WebServerInfo>,
  21. hot_reload: Option<HotReloadState>,
  22. ) -> Result<RecommendedWatcher> {
  23. let mut last_update_time = chrono::Local::now().timestamp();
  24. // file watcher: check file change
  25. let allow_watch_path = config
  26. .dioxus_config
  27. .web
  28. .watcher
  29. .watch_path
  30. .clone()
  31. .unwrap_or_else(|| vec![PathBuf::from("src"), PathBuf::from("examples")]);
  32. let watcher_config = config.clone();
  33. let mut watcher = notify::recommended_watcher(move |info: notify::Result<notify::Event>| {
  34. let config = watcher_config.clone();
  35. if let Ok(e) = info {
  36. if chrono::Local::now().timestamp() > last_update_time {
  37. let mut needs_full_rebuild;
  38. if let Some(hot_reload) = &hot_reload {
  39. // find changes to the rsx in the file
  40. let mut rsx_file_map = hot_reload.file_map.lock().unwrap();
  41. let mut messages: Vec<Template<'static>> = Vec::new();
  42. // In hot reload mode, we only need to rebuild if non-rsx code is changed
  43. needs_full_rebuild = false;
  44. for path in &e.paths {
  45. // if this is not a rust file, rebuild the whole project
  46. if path.extension().and_then(|p| p.to_str()) != Some("rs") {
  47. needs_full_rebuild = true;
  48. break;
  49. }
  50. match rsx_file_map.update_rsx(path, &config.crate_dir) {
  51. Ok(UpdateResult::UpdatedRsx(msgs)) => {
  52. messages.extend(msgs);
  53. needs_full_rebuild = false;
  54. }
  55. Ok(UpdateResult::NeedsRebuild) => {
  56. needs_full_rebuild = true;
  57. }
  58. Err(err) => {
  59. log::error!("{}", err);
  60. }
  61. }
  62. }
  63. if needs_full_rebuild {
  64. // Reset the file map to the new state of the project
  65. let FileMapBuildResult {
  66. map: new_file_map,
  67. errors,
  68. } = FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
  69. for err in errors {
  70. log::error!("{}", err);
  71. }
  72. *rsx_file_map = new_file_map;
  73. } else {
  74. for msg in messages {
  75. let _ = hot_reload.messages.send(msg);
  76. }
  77. }
  78. } else {
  79. needs_full_rebuild = true;
  80. }
  81. if needs_full_rebuild {
  82. match build_with() {
  83. Ok(res) => {
  84. last_update_time = chrono::Local::now().timestamp();
  85. #[allow(clippy::redundant_clone)]
  86. print_console_info(
  87. &config,
  88. PrettierOptions {
  89. changed: e.paths.clone(),
  90. warnings: res.warnings,
  91. elapsed_time: res.elapsed_time,
  92. },
  93. web_info.clone(),
  94. );
  95. #[cfg(feature = "plugin")]
  96. let _ = PluginManager::on_serve_rebuild(
  97. chrono::Local::now().timestamp(),
  98. e.paths,
  99. );
  100. }
  101. Err(e) => log::error!("{}", e),
  102. }
  103. }
  104. }
  105. }
  106. })
  107. .unwrap();
  108. for sub_path in allow_watch_path {
  109. if let Err(err) = watcher.watch(
  110. &config.crate_dir.join(sub_path),
  111. notify::RecursiveMode::Recursive,
  112. ) {
  113. log::error!("Failed to watch path: {}", err);
  114. }
  115. }
  116. Ok(watcher)
  117. }
  118. #[derive(Clone)]
  119. pub struct HotReloadState {
  120. pub messages: broadcast::Sender<Template<'static>>,
  121. pub file_map: Arc<Mutex<FileMap<HtmlCtx>>>,
  122. }