vite-ssr
vite-ssr copied to clipboard
Add built-in production server and expose server APIs
It doesn't make sense to re-implement production server every time.
Similarly to vite preview
, there could be vite-ssr preview
that runs a local web server.
Also, there should be lower-level exports (say in vite-ssr/server
) for:
-
renderHtml
(so that the end user doesn't need to deal with importing fromdist
folder, suppress type warnings, etc.) -
createApp
or something along the lines, an Express/Connect app that doesn't listen by itself but could be injected into own http server
Thanks for the suggestions.
there could be vite-ssr preview that runs a local web server.
While this is possible, a production server normally needs more logic than just running vite-ssr
. In a typical setup, your production server will also run Express/Koa/Fastify/etc to serve your API (which can be consumed by the rendering app). This logic is completely custom and is not something that a generic local server in vite-ssr
can handle.
Apart from that, vite-ssr
is unopiniated about your production setup, meaning you can run in Express.js, in a serverless platform like Vercel/Netlify, or even in a Cloudflare Worker. All of them have enough differences that makes it hard to create a "preview" local server that fits most people (CF Workers are not even Node.js).
renderHtml (so that the end user doesn't need to deal with importing from dist folder, suppress type warnings, etc.)
Unless I'm missing something, doing import renderHtml from 'vite-ssr/server'
would need to assume there is a build step for the production server (so we can map the import to your local dist
folder and bundle it), which might not be true for some setups. That's why right now you need to import manually the built files, to make it agnostic from the platform/setup you use in production.
I agree it's not the best experience, though, and I would like to hear alternatives that improve DX but keep this library agnostic enough to be used anywhere.
For example, there's also Vitedge, which is more opinionated and takes over the build step for the server (Cloudflare Worker in this case). Therefore, it can provide easy syntax like import xxx from 'vitedge/worker'
because it controls how things are bundled in production.
createApp or something along the lines, an Express/Connect app that doesn't listen by itself but could be injected into own http server
I guess this is already answered but just to be more explicit, this might not work with every setup/platform such as Vercel (serverless functions that don't need Express.js).
I'll keep it in mind, though, and see if there's anything that can be done to improve this part 👍
While this is possible, a production server normally needs more logic than just running vite-ssr. In a typical setup, your production server will also run Express/Koa/Fastify/etc to serve your API (which can be consumed by the rendering app).
Not really. You're explaining the behemoth approach, which has been long discouraged. In a typical modern setup, each HTTP service does solely its own job. One doesn't mix SSR and API server in the same process, this is an anti-pattern. So running a dedicated SSR server is a typical setup in a proper modern architecture.
If several HTTP services are to live under the same domain name (in production), one uses wrapping HTTP routers such as Kubernetes ingress rules, or - in simpler setups - nginx running in sidecar (or even the same) container.
For someone who still wants a behemoth HTTP server doing everything, I suggested lower-level createApp
API (an Express app that could be used along with Express/Koa/etc. API server).
Now then, for someone who doesn't even need a HTTP server (such as certain serverless environments), you would expose renderHtml
.
Unless I'm missing something, doing import renderHtml from 'vite-ssr/server' would need to assume there is a build step for the production server (so we can map the import to your local dist folder and bundle it), which might not be true for some setups.
Why would it need a build step? It might have one but it may live happily without it.
It could dynamically require
from process.cwd() + "/dist"
and/or use user-provided path with something like const renderHtml = createHtmlRenderer({ dist: path.resolve(__dirname, "dist") }
.
I 100% agree about being un-opinionated. However, that doesn't mean you can't expose typical reusable functions and/or runnable scripts. I don't see anything opinionated in my suggestions above, it's simply about reducing copy/paste between projects and covering the low-level logic of working with manifests.
We can have vite-ssr preview
script like how vite preview
does. It could create a custom server with http
module in nodejs.
@kadiryazici Yeah, I'm adding preview
to Vitedge, which wraps this package, so I will probably implement it here as well. While I'm at that, I will probably make that logic public so anyone can import it in a production Node server.