bluwy / create-vite-extra

Extra Vite templates
MIT License
380 stars 60 forks source link

React Streaming example is different than the React recomendation #61

Open drewdecarme opened 2 days ago

drewdecarme commented 2 days ago

This is more of a clarification question (or a series of them) than it is an issue.

I was reading through the React + TS + Streaming example that you have and it's wildly straight forward. However, I was reading React's documentation and the suggested recommendation differs to a large extent from what's in the example.

https://react.dev/reference/react-dom/server/renderToPipeableStream#rendering-a-react-tree-as-html-to-a-nodejs-stream

The clear difference is that in your example you're importing a HTML template that has a comment to be replaced with the SSR react tree, however React bolds this text in their docs

Along with the root component, you need to provide a list of bootstrap <script> paths. Your root component should return the entire document including the root <html> tag.

Below is your example where the manifest during the Dev build get's inserted into the template.

 template = await fs.readFile('./index.html', 'utf-8')
 template = await vite.transformIndexHtml(url, template)

Below is React's example. The <App /> in this case would be the stuff in the entry-server.tsx and then the options would be the options that are fed to renderToPipeableStream.

import { renderToPipeableStream } from 'react-dom/server';

// The route handler syntax depends on your backend framework
app.use('/', (request, response) => {
  const { pipe } = renderToPipeableStream(<App />, {
    bootstrapScripts: ['/main.js'],
    onShellReady() {
      response.setHeader('content-type', 'text/html');
      pipe(response);
    }
  });
});

At this point, I haven't found a way to adapt your example with what React suggests for the sole reason of not being able to correctly find the in memory built / compiled assets.

Is there a way to do what React is suggesting where you insert the built assets URLs into either the bootstrapScripts or the bootstrapModules option fields to replace the entire html node in the document? Or is this the recommendation that Vite suggests?

The only other thing I can really think of to make this happen is to create a Virtual Module to be able to read the manifest files in the build, but again that would be reliant on being able to get a manifest during the development server being run.

Thanks!

bluwy commented 1 day ago

The React API has the assumption that <App /> is the root HTML that renders <html> and everything else. The templates setup here is different where index.html dictates that instead, the <App /> is only partial. So what the React API is suggesting doesn't really fit for us. We're combining our index.html with React's stream in the onShellReady hook to resolve this, and as a result because the scripts are already included the HTML:

You don't really need to tell React anymore to append any other scripts as we've handled that ourselves. So in this case, you can ignore its suggestion.