Răsfoiți Sursa

Partially Fix Hotreload (#2557)

* fix: template names

* fix: hot reload "resets" after reload

* revision: ensure all paths are split by `/`

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
Miles Murgaw 1 an în urmă
părinte
comite
7f6f0de085

+ 1 - 0
Cargo.lock

@@ -2375,6 +2375,7 @@ dependencies = [
 name = "dioxus-core"
 version = "0.5.2"
 dependencies = [
+ "const_format",
  "dioxus",
  "dioxus-html",
  "dioxus-ssr",

+ 1 - 0
Cargo.toml

@@ -101,6 +101,7 @@ prettyplease = { version = "0.2.16", features = ["verbatim"] }
 manganis-cli-support = { git = "https://github.com/DogeDark/dioxus-collect-assets/", features = ["html"] }
 manganis = { version = "0.2.1" }
 interprocess = { version = "1.2.2", package = "interprocess-docfix" }
+const_format = "0.2.32"
 
 lru = "0.12.2"
 async-trait = "0.1.77"

+ 1 - 0
packages/core/Cargo.toml

@@ -23,6 +23,7 @@ tracing = { workspace = true }
 serde = { version = "1", features = ["derive"], optional = true }
 generational-box = { workspace = true }
 rustversion = "1.0.17"
+const_format = { workspace = true }
 
 [dev-dependencies]
 tokio = { workspace = true, features = ["full"] }

+ 2 - 0
packages/core/src/lib.rs

@@ -91,3 +91,5 @@ pub mod prelude {
         TemplateAttribute, TemplateNode, VNode, VNodeInner, VirtualDom,
     };
 }
+
+pub use const_format;

+ 2 - 1
packages/core/src/virtual_dom.rs

@@ -584,8 +584,9 @@ impl VirtualDom {
                 // Recurse into the dynamic nodes of the existing mounted node to see if the template is alive in the tree
                 fn check_node_for_templates(node: &crate::VNode, template: Template) -> bool {
                     let this_template_name = node.template.get().name.rsplit_once(':').unwrap().0;
+                    let other_template_name = template.name.rsplit_once(':').unwrap().0;
 
-                    if this_template_name == template.name.rsplit_once(':').unwrap().0 {
+                    if this_template_name == other_template_name {
                         return true;
                     }
 

+ 12 - 3
packages/hot-reload/src/websocket.rs

@@ -107,16 +107,20 @@ async fn ws_handler(
     ws.on_upgrade(move |socket| ws_reload_handler(socket, state))
 }
 
-async fn ws_reload_handler(mut socket: WebSocket, state: HotReloadReceiver) {
+/// Handles full-reloads (e.g. page refresh).
+async fn ws_reload_handler(mut socket: WebSocket, mut state: HotReloadReceiver) {
     let mut rx = state.reload.subscribe();
 
     loop {
         rx.recv().await.unwrap();
 
-        let _ = socket.send(Message::Text(String::from("reload"))).await;
+        // We need to clear the cached templates because we are doing a "fresh" build
+        // and the templates may force the page to a state before the full reload.
+        state.clear_all_modified_templates();
 
         // ignore the error
-        println!("forcing reload");
+        let _ = socket.send(Message::Text(String::from("reload"))).await;
+        tracing::info!("forcing reload");
 
         // flush the errors after recompling
         rx = rx.resubscribe();
@@ -167,6 +171,11 @@ impl HotReloadReceiver {
             .collect()
     }
 
+    /// Clears the cache of modified templates.
+    pub fn clear_all_modified_templates(&mut self) {
+        self.template_updates.lock().unwrap().clear();
+    }
+
     /// Send a hot reloading message to the client
     pub fn send_message(&self, msg: HotReloadMsg) {
         // Before we send the message, update the list of changed templates

+ 1 - 4
packages/rsx/src/hot_reload/hot_reloading_file_map.rs

@@ -305,10 +305,7 @@ pub fn template_location(old_start: proc_macro2::LineColumn, file: &Path) -> Str
     let line = old_start.line;
     let column = old_start.column + 1;
 
-    #[cfg(not(target_os = "windows"))]
-    let path = file.to_string_lossy().to_string();
-
-    #[cfg(target_os = "windows")]
+    // Always ensure the path components are separated by `/`.
     let path = file
         .components()
         .map(|c| c.as_os_str().to_string_lossy())

+ 6 - 9
packages/rsx/src/renderer.rs

@@ -79,16 +79,13 @@ impl<'a> TemplateRenderer<'a> {
                 // Get the root:column:id tag we'll use as the ID of the template
                 let root_col = self.get_root_col_id();
 
+                // Replace `\\` to `/` and then replace `\` to `/`
                 quote! {
-                    concat!(
-                        file!(),
-                        ":",
-                        line!(),
-                        ":",
-                        column!(),
-                        ":",
-                        #root_col
-                    )
+                    {
+                        const PATH: &str = dioxus_core::const_format::str_replace!(file!(), "\\\\", "/");
+                        const NORMAL: &str = dioxus_core::const_format::str_replace!(PATH, '\\', "/");
+                        dioxus_core::const_format::concatcp!(NORMAL, ':', line!(), ':', column!(), ':', #root_col)
+                    }
                 }
             }
         }