vite-plugin-react icon indicating copy to clipboard operation
vite-plugin-react copied to clipboard

vite hot reloading does not work with server side streaming with renderToPipeableStream [react 18]

Open jordanst3wart opened this issue 1 year ago • 3 comments

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

jordanst3wart avatar Sep 20 '23 14:09 jordanst3wart

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?

ArnaudBarre avatar Sep 21 '23 16:09 ArnaudBarre

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.

cyco130 avatar Sep 21 '23 16:09 cyco130

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.

brillout avatar Sep 21 '23 17:09 brillout

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!

ArnaudBarre avatar May 21 '24 09:05 ArnaudBarre