DioxusLabs / DioxusLabs/dioxus
Fullstack + WASM split hydration issues
- Dominant language
- Rust
- Stars
- 39.1k
- Forks
- 1.9k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 4
Description
**Problem**
When enabling both the `fullstack` and `wasm-split` features, hydration does not work as expected.
Using the default generated project:
- If no extra flags are passed to the CLI, `__wasm_split.js` is not generated, and the echo server function does not load. The blog page navigation requests new pages from the server, and continues to function.
- If the `--wasm-split` CLI flag is supplied, then hydration fails in the browser with the following error:
wasm-bindgen: imported JS function that was not marked as `catch` threw an error: Cannot read properties of undefined (reading 'toString')
```
patch_console.js:1 wasm-bindgen: imported JS function that was not marked as `catch` threw an error: Cannot read properties of undefined (reading 'toString')
Stack:
TypeError: Cannot read properties of undefined (reading 'toString')
at RawInterpreter.hydrate_node (http://127.0.0.1:8080/wasm/snippets/dioxus-interpreter-js-7c763d722cc97db1/inline0.js:2:5176)
at RawInterpreter.hydrate (http://127.0.0.1:8080/wasm/snippets/dioxus-interpreter-js-7c763d722cc97db1/inline0.js:2:5653)
at http://127.0.0.1:8080/wasm/dx-hydration.js:1043:14
at logError (http://127.0.0.1:8080/wasm/dx-hydration.js:93:18)
at imports.wbg.__wbg_hydrate_ae79e1fd0196a8a5 (http://127.0.0.1:8080/wasm/dx-hydration.js:1038:70)
at dx_hydration-8219b91c273f630c.wasm._ZN10dioxus_web9hydration7hydrate44_$LT$impl$u20$dioxus_web..dom..WebsysDom$GT$24start_hydration_at_scope17h26c99c773f933315E (http://127.0.0.1:8080/wasm/dx-hydration_bg.wasm:wasm-function[783]:0xbe2e9)
at dx_hydration-8219b91c273f630c.wasm._ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE (http://127.0.0.1:8080/wasm/dx-hydration_bg.wasm:wasm-function[855]:0xcae71)
at dx_hydration-8219b91c273f630c.wasm._ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E (http://127.0.0.1:8080/wasm/dx-hydration_bg.wasm:wasm-function[4697]:0x1a144e)
at dx_hydration-8219b91c273f630c.wasm._ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E (http://127.0.0.1:8080/wasm/dx-hydration_bg.wasm:wasm-function[3298]:0x16da78)
at dx_hydration-8219b91c273f630c.wasm.closure224 externref shim (http://127.0.0.1:8080/wasm/dx-hydration_bg.wasm:wasm-function[7747]:0x20bb5f)
console.error @ patch_console.js:1
logError @ dx-hydration.js:102
imports.wbg.__wbg_hydrate_ae79e1fd0196a8a5 @ dx-hydration.js:1038
$_ZN10dioxus_web9hydration7hydrate44_$LT$impl$u20$dioxus_web..dom..WebsysDom$GT$24start_hydration_at_scope17h26c99c773f933315E @ dx-hydration_bg.wasm:0xbe2e9
$_ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE @ dx-hydration_bg.wasm:0xcae71
$_ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E @ dx-hydration_bg.wasm:0x1a144e
$_ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E @ dx-hydration_bg.wasm:0x16da78
$closure224 externref shim @ dx-hydration_bg.wasm:0x20bb5f
__wbg_adapter_72 @ dx-hydration.js:352
real @ dx-hydration.js:200
setTimeout
(anonymous) @ dx-hydration.js:1767
handleError @ dx-hydration.js:124
imports.wbg.__wbg_setTimeout_db2dbaeefb6f39c7 @ dx-hydration.js:1766
$_ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE @ dx-hydration_bg.wasm:0xc985f
$_ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E @ dx-hydration_bg.wasm:0x1a144e
$_ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E @ dx-hydration_bg.wasm:0x16da78
$closure224 externref shim @ dx-hydration_bg.wasm:0x20bb5f
__wbg_adapter_72 @ dx-hydration.js:352
real @ dx-hydration.js:200
dx-hydration.js:103 Uncaught TypeError: Cannot read properties of undefined (reading 'toString')
at RawInterpreter.hydrate_node (inline0.js:2:5176)
at RawInterpreter.hydrate (inline0.js:2:5653)
at dx-hydration.js:1043:14
at logError (dx-hydration.js:93:18)
at imports.wbg.__wbg_hydrate_ae79e1fd0196a8a5 (dx-hydration.js:1038:70)
at dx_hydration-8219b91c273f630c.wasm._ZN10dioxus_web9hydration7hydrate44_$LT$impl$u20$dioxus_web..dom..WebsysDom$GT$24start_hydration_at_scope17h26c99c773f933315E (dx-hydration_bg.wasm:0xbe2e9)
at dx_hydration-8219b91c273f630c.wasm._ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE (dx-hydration_bg.wasm:0xcae71)
at dx_hydration-8219b91c273f630c.wasm._ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E (dx-hydration_bg.wasm:0x1a144e)
at dx_hydration-8219b91c273f630c.wasm._ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E (dx-hydration_bg.wasm:0x16da78)
at dx_hydration-8219b91c273f630c.wasm.closure224 externref shim (dx-hydration_bg.wasm:0x20bb5f)
hydrate_node @ inline0.js:2
hydrate @ inline0.js:2
(anonymous) @ dx-hydration.js:1043
logError @ dx-hydration.js:93
imports.wbg.__wbg_hydrate_ae79e1fd0196a8a5 @ dx-hydration.js:1038
$_ZN10dioxus_web9hydration7hydrate44_$LT$impl$u20$dioxus_web..dom..WebsysDom$GT$24start_hydration_at_scope17h26c99c773f933315E @ dx-hydration_bg.wasm:0xbe2e9
$_ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE @ dx-hydration_bg.wasm:0xcae71
$_ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E @ dx-hydration_bg.wasm:0x1a144e
$_ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E @ dx-hydration_bg.wasm:0x16da78
$closure224 externref shim @ dx-hydration_bg.wasm:0x20bb5f
__wbg_adapter_72 @ dx-hydration.js:352
real @ dx-hydration.js:200
setTimeout
(anonymous) @ dx-hydration.js:1767
handleError @ dx-hydration.js:124
imports.wbg.__wbg_setTimeout_db2dbaeefb6f39c7 @ dx-hydration.js:1766
$_ZN10dioxus_web6launch18launch_virtual_dom28_$u7b$$u7b$closure$u7d$$u7d$17h8fe5067c3ea32bfbE @ dx-hydration_bg.wasm:0xc985f
$_ZN20wasm_bindgen_futures5queue5Queue3new28_$u7b$$u7b$closure$u7d$$u7d$17hbef9abee52a3b198E @ dx-hydration_bg.wasm:0x1a144e
$_ZN136_$LT$dyn$u20$core..ops..function..FnMut$LT$$LP$A$C$$RP$$GT$$u2b$Output$u20$$u3d$$u20$R$u20$as$u20$wasm_bindgen..closure..WasmClosure$GT$8describe6invoke17h894e8e2d01961364E @ dx-hydration_bg.wasm:0x16da78
$closure224 externref shim @ dx-hydration_bg.wasm:0x20bb5f
__wbg_adapter_72 @ dx-hydration.js:352
real @ dx-hydration.js:200
```
The cause of the stacktrace appears to be: the `data-node-hydration` ID is greater than the number of nodes being passed to the `hydrate` function.
If I manually alter the `dioxus-interpreter-js/inline0.js` file being served to return early if the node ID does not exist e.g.:
...}hydrate_node(hydrateNode,ids){let split=hydrateNode.getAttribute("data-node-hydration").split(","),id=ids[parseInt(split[0])];if (!id) return;...
```diff
hydrate_node(hydrateNode: HTMLElement, ids: { [key: number]: number }) {
const hydration = hydrateNode.getAttribute("data-node-hydration");
const split = hydration!.split(",");
const id = ids[parseInt(split[0])];
+ if (!id) return;
this.nodes[id] = hydrateNode;
```
, then the console errors go away, the echo server function works as expected, and the blog navigation is handled client-side. I can see from the network trace that the WASM has been split, and multiple modules are being loaded.
_However_, a non-hydrated duplicate of the home page is shown below the working, hydrated version:
Double page screenshot
**Steps To Reproduce**
Steps to reproduce the behavior:
- Create a new project via `dx new`:
```
> dx new foo ╯
✔ 🤷 Which sub-template should be expanded? · Bare-Bones
✔ 🤷 Do you want to use Dioxus Fullstack? · true
✔ 🤷 Do you want to use Dioxus Router? · true
✔ 🤷 Do you want to use Tailwind CSS? · false
✔ 🤷 Do you want to include prompts for LLMs? · false
✔ 🤷 Which platform do you want DX to serve by default? · Web
```
- Add the `wasm-split` feature to `dioxus` in `Cargo.toml`:
```toml
dioxus = { version = "0.7.0-rc.0", features = ["router","fullstack","wasm-split"] }
```
- Serve with the `wasm-split` feature:
```
dx serve --web --wasm-split
```
**Expected behavior**
A single, hydrated copy of the app should be rendered without errors.
**Screenshots**
See above.
**Environment:**
- Dioxus version: 0.7.0-rc.0, CLI version `main@80731da25a698b655b1679e2e9deaa2959740d58` to avoid https://github.com/DioxusLabs/dioxus/issues/4514.
- Rust version: 1.89.0 stable
- OS info: macOS 15.6.1
- App platform: web
**Questionnaire**
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.