Merge pull request #24 from jkelleyrtp/jk/ssr_lazy
feat: add more to ssr renderer
This commit is contained in:
3 files changed
+80
-9
No files matched your search
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"rust-analyzer.inlayHints.enable": false
|
|
||||||
}
|
|
||||||
+19
-2
@@ -14,7 +14,7 @@ let mut vdom = VirtualDOM::new(App);
|
|||||||
let _ = vdom.rebuild();
|
let _ = vdom.rebuild();
|
||||||
|
|
||||||
// Render the entire virtualdom from the root
|
// Render the entire virtualdom from the root
|
||||||
let text = dioxus_ssr::render_vdom(&vdom, |c| c);
|
let text = dioxus::ssr::render_vdom(&vdom, |c| c);
|
||||||
assert_eq!(text, "<div>hello world!</div>")
|
assert_eq!(text, "<div>hello world!</div>")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -40,12 +40,29 @@ let text = dioxus::ssr::render_vdom(App, |cfg| cfg.pre_render(true));
|
|||||||
Dioxus SSR can also be to render on the server. Obviously, you can just render the VirtualDOM to a string and send that down.
|
Dioxus SSR can also be to render on the server. Obviously, you can just render the VirtualDOM to a string and send that down.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let text = dioxus_ssr::render_vdom(&vdom, |c| c);
|
let text = dioxus::ssr::render_vdom(&vdom, |c| c);
|
||||||
assert_eq!(text, "<div>hello world!</div>")
|
assert_eq!(text, "<div>hello world!</div>")
|
||||||
```
|
```
|
||||||
|
|
||||||
The rest of the space - IE doing this more efficiently, caching the virtualdom, etc, will all need to be a custom implementation for now.
|
The rest of the space - IE doing this more efficiently, caching the virtualdom, etc, will all need to be a custom implementation for now.
|
||||||
|
|
||||||
|
## Usage without a VirtualDom
|
||||||
|
|
||||||
|
Dioxus SSR needs an arena to allocate from - whether it be the VirtualDom or a dedicated Bump allocator. To render `rsx!` directly to a string, you'll want to create an `SsrRenderer` and call `render_lazy`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let text = dioxus::ssr::SsrRenderer::new().render_lazy(rsx!{
|
||||||
|
div { "hello world" }
|
||||||
|
});
|
||||||
|
assert_eq!(text, "<div>hello world!</div>")
|
||||||
|
```
|
||||||
|
|
||||||
|
This can be automated with the `render_lazy!` macro:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let text = render_lazy!(rsx!( div { "hello world" } ));
|
||||||
|
```
|
||||||
|
|
||||||
## Usage in static site generation
|
## Usage in static site generation
|
||||||
|
|
||||||
Dioxus SSR is a powerful tool to generate static sites. Using Dioxus for static site generation _is_ a bit overkill, however. The new documentation generation library, Doxie, is essentially Dioxus SSR on steroids designed for static site generation with client-side hydration.
|
Dioxus SSR is a powerful tool to generate static sites. Using Dioxus for static site generation _is_ a bit overkill, however. The new documentation generation library, Doxie, is essentially Dioxus SSR on steroids designed for static site generation with client-side hydration.
|
||||||
|
|||||||
+61
-4
@@ -12,8 +12,49 @@
|
|||||||
|
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use dioxus_core::exports::bumpalo;
|
||||||
|
use dioxus_core::nodes::IntoVNode;
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
|
|
||||||
|
macro_rules! render_lazy {
|
||||||
|
($f:expr) => {
|
||||||
|
$crate::SsrRenderer::new().render_lazy($f)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SsrRenderer {
|
||||||
|
inner: bumpalo::Bump,
|
||||||
|
}
|
||||||
|
impl Default for SsrRenderer {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: bumpalo::Bump::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SsrRenderer {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
SsrRenderer::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_lazy<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(
|
||||||
|
&'a self,
|
||||||
|
f: LazyNodes<'a, F>,
|
||||||
|
) -> String {
|
||||||
|
let factory = NodeFactory::new(&self.inner);
|
||||||
|
let root = f.into_vnode(factory);
|
||||||
|
format!(
|
||||||
|
"{:}",
|
||||||
|
TextRenderer {
|
||||||
|
cfg: SsrConfig::default(),
|
||||||
|
root: &root,
|
||||||
|
vdom: None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_vnode(vnode: &VNode, string: &mut String) {}
|
pub fn render_vnode(vnode: &VNode, string: &mut String) {}
|
||||||
|
|
||||||
pub fn render_vdom(dom: &VirtualDom, cfg: impl FnOnce(SsrConfig) -> SsrConfig) -> String {
|
pub fn render_vdom(dom: &VirtualDom, cfg: impl FnOnce(SsrConfig) -> SsrConfig) -> String {
|
||||||
@@ -52,19 +93,19 @@ pub fn render_vdom_scope(vdom: &VirtualDom, scope: ScopeId) -> Option<String> {
|
|||||||
/// let output = format!("{}", renderer);
|
/// let output = format!("{}", renderer);
|
||||||
/// assert_eq!(output, "<div>hello world</div>");
|
/// assert_eq!(output, "<div>hello world</div>");
|
||||||
/// ```
|
/// ```
|
||||||
pub struct TextRenderer<'a> {
|
pub struct TextRenderer<'a, 'b> {
|
||||||
vdom: Option<&'a VirtualDom>,
|
vdom: Option<&'a VirtualDom>,
|
||||||
root: &'a VNode<'a>,
|
root: &'b VNode<'a>,
|
||||||
cfg: SsrConfig,
|
cfg: SsrConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for TextRenderer<'_> {
|
impl Display for TextRenderer<'_, '_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
self.html_render(self.root, f, 0)
|
self.html_render(self.root, f, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TextRenderer<'a> {
|
impl<'a> TextRenderer<'a, '_> {
|
||||||
pub fn from_vdom(vdom: &'a VirtualDom, cfg: SsrConfig) -> Self {
|
pub fn from_vdom(vdom: &'a VirtualDom, cfg: SsrConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cfg,
|
cfg,
|
||||||
@@ -341,4 +382,20 @@ mod tests {
|
|||||||
dom.rebuild();
|
dom.rebuild();
|
||||||
dbg!(render_vdom(&dom, |c| c));
|
dbg!(render_vdom(&dom, |c| c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lazy() {
|
||||||
|
let p1 = SsrRenderer::new().render_lazy(rsx! {
|
||||||
|
div {
|
||||||
|
"ello"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let p2 = render_lazy!(rsx! {
|
||||||
|
div {
|
||||||
|
"ello"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert_eq!(p1, p2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user