DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
20.46k stars 786 forks source link

Add a ton of comments to rsx/hotreload, add snapshot testing, refactor a bit to simplify the crate #2130

Closed jkelleyrtp closed 6 months ago

jkelleyrtp commented 6 months ago

This a precursor to implementing proper for/if/component hotreloading, and eventually, component prop hotreloading.

The module is somewhat complex, but all this documentation should make understanding and maintaining hotreloading easier in the future.

I did my best to not introduce any functionality changes with this beyond adding some new methods where we'll inject location information.

There's some challenges I ran into with the model I'm conceptualizing, but they're not too bad:

Anyways, I want to make this a good checkpoint before venturing even deeper into this problem space.

It might be worth building on top of this PR to get for loops implemented (the simplest of the set), and then if chains, and then finally components, since each change would be small but important.

I might've done a little too much refactoring (removing all ToTokens), now that I think about it, since we could just use interior mutability to set location information after parsing the nodes.


I'm hoping we can add in some plumbing to expose simple literal expressions and/or serializable types as hotreloading candidates. If we could get that working, then you'd be able to hotreload classes on stuff like Link, which IMO is an incredible achievement for the rust ecosystem.

Link { class: "some-tailwind-class" }

With the theoretical serialization extension, you'd be able to drive complex structures from a devtool, ala:

// in dev mode we'd insert some glue to check if these are serializable 
let settings = use_signal(|| SomeSerializableSettings::new());

// that would get plumbed into a component that renders the settings
rsx! {
     SettingsPannel { settings }               // <---------------  we could drive `settings` from a devtool instantly
}

ALSO I just want to put this out there - we could enable hot reload of statics/consts too, under some circumstances

This example is technically reloadable:

   let caption_style = r"
        font-size: 32px;
        margin: 0;
        color: white;
        text-align: center;
    ";

    rsx!(
        div { style: "{container_style}",

This would be further in the future, but if you could prove that the const/static doesn't escape tracked contexts, you can reload it.