vite-plugin-react
vite-plugin-react copied to clipboard
vite hot reloading does not work with server side streaming with renderToPipeableStream [react 18]
Describe the bug
Bug/feature request: Vite hot reloading does not work with react 18 renderToPipeableStream (https://react.dev/reference/react-dom/server/renderToPipeableStream). renderToPipeableStream
others very significant improvements compared to rendering to a string.
The preamble is not installed, as the root is considered mounted, and waiting for hydration.
The following is logged to the console:
Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong. See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201
There is a script work around here: https://github.com/letientai299/vite-react-ssr-typescript/blob/master/src/refresh-hack.js
It also dangerously sets inner html here: https://github.com/letientai299/vite-react-ssr-typescript/blob/6b0b98a2947e1b2d8bbfb610da1e53e474395fe2/src/Html.tsx#L17
Reproduction
https://github.com/letientai299/vite-react-ssr-typescript
Steps to reproduce
https://github.com/letientai299/vite-react-ssr-typescript#react-refresh-preamble-was-not-loaded
System Info
System:
OS: macOS 13.5.2
CPU: (10) arm64 Apple M2 Pro
Memory: 163.73 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.16.1 - /usr/local/bin/node
npm: 9.5.1 - /usr/local/bin/npm
pnpm: 8.7.4 - ~/Documents/PropCode/app/node_modules/.bin/pnpm
Browsers:
Chrome: 117.0.5938.88
Safari: 16.6
Used Package Manager
pnpm
Logs
From the console: Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong. See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
There was already some discussions here: https://github.com/vitejs/vite-plugin-react/issues/14
@cyco130 @brillout have you already encounter/look into/solve this issue?
For hot reloading to work, one has to inject the Vite client and a piece of code called the React Refresh preamble. Normally transformIndexHtml
takes care of both but it expects a string so it doesn’t work with streaming.
So you have to inject them yourself. Here’s the piece of code that does it for Rakkas: https://github.com/rakkasjs/rakkasjs/blob/ff95ee58ace4e262c320cc26884738ad0a74815c/packages/rakkasjs/src/features/pages/middleware.tsx#L750
Edit: The preamble need also to be async
.
I didn't encounter this, but that's most likely due to the fact that most vite-plugin-ssr React users don't use streaming.
I'm pasting my answer from #293:
I think this part does it well: https://github.com/bluwy/create-vite-extra/pull/54/files?w=1#diff-fec94eeb5a435041f70a99f5a079623b3be9d4be73d174a3648ded111dc0038aR68-R83
The other solution would be to have React render everything and have something like this in a part of the react tree in charge of the header: https://github.com/rakkasjs/rakkasjs/blob/ff95ee58ace4e262c320cc26884738ad0a74815c/packages/rakkasjs/src/features/pages/middleware.tsx#L750
For now I consider this concern outside of the scope of the plugin, but if you think anything in this plugin could make things more easy for streaming, please open an issue to discuss the need!