Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asset integration with elements + hotreloading #1955

Open
jkelleyrtp opened this issue Feb 20, 2024 · 1 comment
Open

asset integration with elements + hotreloading #1955

jkelleyrtp opened this issue Feb 20, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@jkelleyrtp
Copy link
Member

jkelleyrtp commented Feb 20, 2024

Specific Demand

I would love to see that somehow our style elements could integrate with bundling to allow hotreloading of CSS just by adding the relevant style tag:

rsx! {
    style { src: "./local_src.css" }
}

This is definitely doable but would require some plumbing. If we could somehow extend regular elements, the asset configuration of images, videos, and more could be done at compile time:

rsx! {
    img { src: "./my_image.png", optimize: true }
}

This is definitely feasible but would require some brainstorming in a good design + architecture.

If I had to design this, I would experiment with dumping all template data into the target dir and then the dx CLI would watch this for updates and run its own asset system against it.

// call rsx
rsx! {
    style { src: "./local_src.css" }
} 

// write serialized template contents 
/target/templates/contents.json
[{
   loc: "src/header/local_src.css:144",
   elements:  { attr: { name: "css", src: "./local_src.css" , namespace: "html" }}
}]

// watch each asset for changes
watch src/data/local_css.css

// force an update to the element, causing it to live reload
dx-apps send-mutation --attribute-changed --el 42 --data-dioxus-hash e7gk310

Ideally the asset system would be integrated into the LaunchBuilder - so any library that uses the launch builder could easily tap into assets just by implementing the regular mutation API. We'd have to expose some way of driving updates to the asset (maybe by updating an associated data-dioxus-hash attribute).

@jkelleyrtp jkelleyrtp added the enhancement New feature or request label Feb 20, 2024
@ealmloff
Copy link
Member

ealmloff commented Feb 20, 2024

API

It might make sense to build this functionality into the rsx macro. We could use some of the information from dioxus-html in the rsx macro (with an option for freya to override it) to capture and map source attributes automatically

It would be nice to map paths in dioxus web for a few different reasons:

  1. To make asset paths between dioxus desktop and dioxus web consistent
  2. To do automatic cache busting
  3. To do more advanced optimizations like url encoded low quality image previews before the whole images loads

mg currently supports all three of the above.

We could expand:

rsx! {
    style { src: "./local_src.css" }
}

into:

rsx! {
    style { src: mg!("./local_src.css") }
}

Then we could reuse the existing bundling and optimization system.

Hot reloading

If we map asset paths and include a hash of the last modified date in the output path (like mg currently does), then we don't need anything special in the renderers for hot reloading. We could just update the source attribute when we notice that asset was changed.

(There is also some overlap with the asset hot reloading api we expose to plugins in #1673)

DX concerns

If this is built into the elements, it could be surprising that using a dynamic source or const value breaks the asset. The current template optimizations we do only improve performance if we have enough information to know an attribute/element is static at compile time, this new API would change behavior.

If I change this code in dioxus web:

style { src: "./local_src.css" }

To this code with a constant:

const MY_CSS_FILE: &str = "./local_src.css";
rsx! {
    style { src: MY_CSS_FILE }
}

Then the path to my local file no longer works.

We could make sources accept a special type that is either const (inline or with the mg! macro) or dynamic with a special constructor:

// This can be used with any String-like value which may be generated at runtime, but paths are not mapped and optimizations are not applied. You also need to manually add it to the list of bundled and watched assets
const MY_CSS_FILE: Asset = Asset::raw("./local_src.css");
rsx! {
    style { src: MY_CSS_FILE }
}

// This works exactly like an inline string. It is automatically optimized, bundled and watched
// This API is nice if I want to store a list of assets like in a carousel while still linking to assets in a cross platform way and optimizing assets
const MY_CSS_FILE: Asset = mg!(file("./local_src.css"));
rsx! {
    style { src: MY_CSS_FILE }
}

// The macro converts literal strings for attributes that accept assets into the static optimized version of the asset
rsx! {
    style { src: "./local_src.css" }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants