Closed phonzammi closed 9 months ago
Your implementation looks great 👍 I think it could be simplified a bit to use res.write()
instead of generators, but I think it's also a matter of preference then.
I think it would be nice to add a streaming implementation. Perhaps as an option in the CLI with this flow: "Vue" > "Streaming or no-streaming" > "JS or TS". Which means we probably need to create a new template-ssr-vue-streaming
and template-ssr-vue-streaming-ts
templates which are largely duplicates of template-ssr-vue
and template-ssr-vue-ts
. Feel free to contribute them!
Your implementation looks great 👍
Thanks
I think it could be simplified a bit to use
res.write()
instead of generators
Yeah, maybe you're right, about using res.write()
, I think you mean to write head & end of the html, right?
I've tried this way, but this way results with hydration mismatch :
const stream = renderToNodeStream(app, ctx)
stream.once('readable', () => {
res.status(200).set({ 'Content-Type': 'text/html' })
res.write(head)
})
stream.on('data', () => {
stream.pipe(res, { end: false })
})
stream.on('end', () => {
res.write(tail)
res.end()
})
stream.on('error', (error) => {
res.setHeader('Content-Type', 'text/json')
res.end(JSON.stringify({ error }))
})
I've also tried this way & doesn't result with hydration mismatch : 💯
const [head, tail] = template.split('<!--app-->')
const encoder = new TextEncoder()
// import { TransformStream } from 'stream/web'
const webStream = new TransformStream({
start(controller) {
controller.enqueue(encoder.encode(head))
},
flush(controller) {
controller.enqueue(encoder.encode(tail))
}
})
// import { Readable, Writable } from 'stream'
const readable = Readable.fromWeb(webStream.readable)
const writable = Writable.fromWeb(webStream.writable)
// import { pipeToNodeWritable } from 'vue/server-renderer'
pipeToNodeWritable(app, ctx, writable)
readable.pipe(res)
And I also want to try it (properly) with Node Transform
Maybe if you have any suggestions, I like to know them 🙏
I think it would be nice to add a streaming implementation. Perhaps as an option in the CLI with this flow: "Vue" > "Streaming or no-streaming" > "JS or TS".
Yes, that would very nice 👍
Feel free to contribute them!
Sure, I'll try
I think your current implementation is perfectly fine too if you used that as the template, as long as the implementation is short and concise. Don't need to sweat on the ideal way to do it for now 😅
Initially though, I was thinking along the lines of (not tested yet):
const [head, tail] = template.split('<!--app-->')
const { stream } = render()
res.write(head)
for await (const chunk of stream) {
res.write(chunk)
}
res.write(tail)
res.end()
If there's errors from the stream, I think it should propagate to the catch handler. Even with my implementation, we might also need to handle the case where a request could be closed before we finish streaming, which means we can stop calling res.write()
thereafter to save on memory. Usually that is detected through the close event.
I think your current implementation is perfectly fine too if you used that as the template, as long as the implementation is short and concise. Don't need to sweat on the ideal way to do it for now 😅
Thanks. That's right, cause it's just an example template. Let me polish it a bit then
Initially though, I was thinking along the lines of (not tested yet):
So I've just try that and surprisingly it works & no hydration mismatch. Awesome 💯
If there's errors from the stream, I think it should propagate to the catch handler. Even with my implementation, we might also need to handle the case where a request could be closed before we finish streaming, which means we can stop calling res.write() thereafter to save on memory. Usually that is detected through the close event.
Nice, thanks for elaborating more
Hi @bluwy, I want to ask for a favor. Could you create a template of Vite + Vue + Streaming SSR ?
FYI, I have created one, but I'm not sure if it is correct. Maybe if you have some spare time, I hope you could take a look and review it too. You can check it in my repo (vite-vue-streaming-ssr).
Hope you have a nice day and night