QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.67k stars 1.29k forks source link

Support SSR in the edge runtime with Vite dev server #1984

Closed zhuhaow closed 6 months ago

zhuhaow commented 1 year ago

Is your feature request related to a problem?

Currently, qwik (or Qwik City) uses Vite, where the dev server expects the SSR code will be run within the node runtime so it loads the code "in-place" in the dev server.

However, SSR may happen in the edge runtime (e.g., Cloudflare Workers). This causes problems when using Qwik City with the dev server. I raised the issue at https://github.com/vitejs/vite/issues/10770 which contains more details.

While there is no support on the Vite side yet, I'm thinking about the compatibility between qwik and the edge runtime when Vite provides some type of support for this.

It seems like in dev mode, qwik expects we can load the script by import (https://github.com/BuilderIO/qwik/blob/main/packages/qwik/src/core/platform/platform.ts#L15) which is generally not available in the edge runtime.

Describe the solution you'd like

I don't know what is a good way to support the edge runtime in this case, or we can also use @qwik-city-plan in dev?

Anyway, since qwik is designed "for the edge", I think it's important that we can SSR in the dev server with local edge runtime emulator (e.g., workerd).

Describe alternatives you've considered

There is no ideal workaround for this. One possible solution is to run build in watch mode and run the edge emulator with the production build, which is not only slow, but we'll lose all nice DX features.

Additional context

No response

manucorporat commented 1 year ago

Qwik should support all enviroments already, i am not sure i understand the issue. Qwik does not depend on any node API, when you build in production, we have integrations that configure correctly the build output to support this platforms https://qwik.builder.io/qwikcity/adaptors/overview/

zhuhaow commented 1 year ago

Yes, for the production deployment it should work.

This is not an issue about the compatibility of qwik codebase itself but the user's code. Currently, we can only test our website in the edge runtime using the production build. However, during development, we may want to work with a faster feedback loop, something like next dev that provides better DX support. My understanding is that currently qwik uses vite --mode ssr as a dev server where SSR is done in node runtime (https://github.com/BuilderIO/qwik/blob/main/packages/qwik-city/buildtime/vite/dev-server.ts#L82).

Node runtime is different from edge runtime in several ways:

  1. They are not the same thing, so they have different behavior. Edge runtimes from different providers have different behavior, they differs more than different node versions.
  2. When we are deploying to the edge, we usually also use other features provided by the edge (e.g., db like Cloudflare KV) which is not available in node runtime, so we just cannot render the page or serve API in node runtime.

Testing the adapter is actually not my goal here. The issue is, how do we, during development, do SSR in edge runtime (e.g., workerd) without creating a production build, so website developers can:

  1. use edge runtime API (e.g., Cloudflare KV) during development and ensure they are not accidentally using node API
  2. have all features provided by qwik dev server/vite dev server such as quick on-the-fly compilation, HMR
manucorporat commented 1 year ago

Vite will soon run in Deno, or it already does. So this should help! Agreed with the general problem though, but it's a bit outside the scope of Qwik, happy to have a Deno + Vite starter! would you like trying to put it together!?

zhuhaow commented 1 year ago

This is harder than developing with dyno since edge runtime is too limited so we cannot run vite inside of it. A possible solution would be to only run SSR code in the edge runtime local sandbox (which we currently don't have a good way to load the script into yet) and do everything else with vite in node/dyno as we are doing now.

As you mentioned, this is not really the scope of Qwik. I'm creating this issue before things are ready on vite side to see if there would be some suggestions or requirements from here.

In the meanwhile, I created issues for vite and workerd at their repos to see how to solve these issues.

When things are ready, I'll try to create a PR to integrate this for Qwik

cayter commented 1 year ago

For Cloudflare bindings to work in local development, I think we can polyfill the platform params like how ppl doing it in SvelteKit here. But I'm not sure if Qwik has corresponding request hook like the one in SvelteKit.

nrgnrg commented 1 year ago

Solid Start include's a dev server hook in the platform adaptors which allows you to set up the dev environment.

For example the cloudflare pages adaptor spins up miniflare to process requests so you can use KV, D1, R2 bindings etc... https://github.com/solidjs/solid-start/blob/main/packages/start-cloudflare-pages/dev-server.js

I'm not sure if Qwik could provide a way to do this, but would be happy to work on the adaptor if it did

zhuhaow commented 1 year ago

Currently, the context (the platform) will be recreated for every request.

https://github.com/BuilderIO/qwik/blob/59ef8e9c6212c9f648de00b5a5d83fbdb5a1583a/packages/qwik-city/buildtime/vite/dev-server.ts#L67

And it seems there is no way to pass user-defined information to this other than do it in vite.config.js, doesn't feel like a good solution.

wmertens commented 6 months ago

we now have the vercel-edge adapter and the vite issue is fixed so presumably this is fixed.