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>
This commit is contained in:
Miles MurgawandJonathan Kelley authored and GitHub committed 2024-07-02 21:45:12 -07:00
1 parent 9567674a63
commit 7f6f0de085
8 files changed
+26 -17

No files matched your search

Generated
+1
View File
@@ -2375,6 +2375,7 @@ dependencies = [
name = "dioxus-core" name = "dioxus-core"
version = "0.5.2" version = "0.5.2"
dependencies = [ dependencies = [
"const_format",
"dioxus", "dioxus",
"dioxus-html", "dioxus-html",
"dioxus-ssr", "dioxus-ssr",
+1
View File
@@ -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-cli-support = { git = "https://github.com/DogeDark/dioxus-collect-assets/", features = ["html"] }
manganis = { version = "0.2.1" } manganis = { version = "0.2.1" }
interprocess = { version = "1.2.2", package = "interprocess-docfix" } interprocess = { version = "1.2.2", package = "interprocess-docfix" }
const_format = "0.2.32"
lru = "0.12.2" lru = "0.12.2"
async-trait = "0.1.77" async-trait = "0.1.77"
+1
View File
@@ -23,6 +23,7 @@ tracing = { workspace = true }
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
generational-box = { workspace = true } generational-box = { workspace = true }
rustversion = "1.0.17" rustversion = "1.0.17"
const_format = { workspace = true }
[dev-dependencies] [dev-dependencies]
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
+2
View File
@@ -91,3 +91,5 @@ pub mod prelude {
TemplateAttribute, TemplateNode, VNode, VNodeInner, VirtualDom, TemplateAttribute, TemplateNode, VNode, VNodeInner, VirtualDom,
}; };
} }
pub use const_format;
+2 -1
View File
@@ -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 // 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 { fn check_node_for_templates(node: &crate::VNode, template: Template) -> bool {
let this_template_name = node.template.get().name.rsplit_once(':').unwrap().0; 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; return true;
} }
+12 -3
View File
@@ -107,16 +107,20 @@ async fn ws_handler(
ws.on_upgrade(move |socket| ws_reload_handler(socket, state)) 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(); let mut rx = state.reload.subscribe();
loop { loop {
rx.recv().await.unwrap(); 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 // ignore the error
println!("forcing reload"); let _ = socket.send(Message::Text(String::from("reload"))).await;
tracing::info!("forcing reload");
// flush the errors after recompling // flush the errors after recompling
rx = rx.resubscribe(); rx = rx.resubscribe();
@@ -167,6 +171,11 @@ impl HotReloadReceiver {
.collect() .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 /// Send a hot reloading message to the client
pub fn send_message(&self, msg: HotReloadMsg) { pub fn send_message(&self, msg: HotReloadMsg) {
// Before we send the message, update the list of changed templates // Before we send the message, update the list of changed templates
@@ -305,10 +305,7 @@ pub fn template_location(old_start: proc_macro2::LineColumn, file: &Path) -> Str
let line = old_start.line; let line = old_start.line;
let column = old_start.column + 1; let column = old_start.column + 1;
#[cfg(not(target_os = "windows"))] // Always ensure the path components are separated by `/`.
let path = file.to_string_lossy().to_string();
#[cfg(target_os = "windows")]
let path = file let path = file
.components() .components()
.map(|c| c.as_os_str().to_string_lossy()) .map(|c| c.as_os_str().to_string_lossy())
+6 -9
View File
@@ -79,16 +79,13 @@ impl<'a> TemplateRenderer<'a> {
// Get the root:column:id tag we'll use as the ID of the template // Get the root:column:id tag we'll use as the ID of the template
let root_col = self.get_root_col_id(); let root_col = self.get_root_col_id();
// Replace `\\` to `/` and then replace `\` to `/`
quote! { quote! {
concat!( {
file!(), const PATH: &str = dioxus_core::const_format::str_replace!(file!(), "\\\\", "/");
":", const NORMAL: &str = dioxus_core::const_format::str_replace!(PATH, '\\', "/");
line!(), dioxus_core::const_format::concatcp!(NORMAL, ':', line!(), ':', column!(), ':', #root_col)
":", }
column!(),
":",
#root_col
)
} }
} }
} }