Reducing inconsistency when developing for non-Node environment by emulating the environment #14288
Replies: 3 comments 3 replies
-
Here's a POC for the alternative "Running in the actual environment". This doesn't work yet as the vite-node client depends on Node.js builtin modules. https://github.com/sapphi-red/vite-envs/tree/run-in-workerd |
Beta Was this translation helpful? Give feedback.
-
@sapphi-red quick note about workerd and eval, a new binding for that has recently been added, so it should indeed be possible to use eval locally now 🙂 (cloudflare/workerd#1338, cloudflare/workers-sdk#4322) |
Beta Was this translation helpful? Give feedback.
-
Hi @sapphi-red! As the creator of Hono and a member of Cloudflare, I'm very curious about this issue. At Hono, we are developing @hono/vite-dev-server to enable the development of Hono applications with Vite. Although it seems specific to Hono, any I believe the optimal solution for this issue would be to handle it within Vite itself, rather than individually across frameworks. We'd like to support you. Perhaps we could use Hono as a test case. Thanks. |
Beta Was this translation helpful? Give feedback.
-
Inconsistency between dev and build when developing for non-Node environment has been a weak point for Vite.
For instance,
@miniflare/kv
or theMiniflare#get*()
global
,process
,Buffer
eval
,new Function
Approach
Use
node:vm
and vite-node to execute the code.Add
ssr.environment
that acceptsViteEnvironment
type.PoC: https://github.com/sapphi-red/vite-envs
Pros
vite-node -e vercel-edge ./src/index.ts
Cons
Deno based environments
There are environments based on Deno. For example, Deno Deploy, Netlify edge functions.
For those environments, I guess a similar approach can be used by running Vite on Deno.
Alternatives
Running in the actual environment
vite-node has the ability to run the server (the part that does the code transform) and the client (the part that does the execution). For example, Vitest runs the client in worker threads.
So instead of running in
node:vm
, we can run the client in the actual environment (e.g.workerd
,deno
).The client uses some Node.js modules but I guess it's possible to remove them conditionally.
The problem is that the client somehow needs to use
eval
or something similar, but it's not allowed in some environments (workerd
).In the case of workerd, I guess it's possible by forking it (related code). But it seems Cloudflare working on something similar, so it might be feasible in the future.
Questions
Should
runModule
andselectModule
be included inViteEnvironmentInfo
?runModule
andselectModule
are the properties I added here.runModule
is a function that receives the Module and request and calls the handler with some context values depending on the environment (Cloudflare, Vercel).selectModule
is a function that receives the request and returns the path of the module that should be executed (Cloudflare, Vercel).I added these functions to make it easier to implement meta-frameworks.
@vite-env/standalone
package is how I expect meta-frameworks to use these functions.I think
runModule
can fit in Vite butselectModule
might be too much.How to support rewriting Node module
import
s?Some environments support a small set of Node.js modules (e.g. Cloudflare, Vercel).
Because
import
cannot be used insidenode:vm
(vm.runInContext
) and we shouldn't exposerequire
, we'll need to rewriteimport foo from 'node:foo'
intoconst foo = globalThis._viteEnvNode.foo
. This is possible byresolveId
+load
hook but I wonder if it's better to include in theViteEnvironment
type. I'm leaning not to include it.Should Vite use a Web Standard-based middleware instead of Node middleware?
Web Standard-based middleware means a middleware that uses
Request
andResponse
from Fetch Standard spec (I'm not sure if there's a widely used term for this). Node middleware means a middleware that useshttp.IncomingMessage
andhttp.ServerResponse
. Web Standard-based middlewares can be easily used in any environments. Non-node environment natively supports them and there's some packages that can convert Node middlewares into Web Standard-based middlewares.The POC runs a separate server alongside with the Vite server, because I wasn't able to convert Node middlewares into Web Standard-based middlewares. (related code 1, related code 2) If Vite uses a Web Standard-based middleware, we can stop doing this separate server thing.
Or another way to solve this is to convert Node middlewares into Web Standard-based middlewares. I found
@fastly/http-compute-js
does this but there's much incompatibility and I guess it's difficult to achieve.References
Beta Was this translation helpful? Give feedback.
All reactions