Release CandidateThe Environment API is generally in the release candidate phase. We’ll maintain stability in the APIs between major releases to allow the ecosystem to experiment and build upon them. However, note that some specific APIs are still considered experimental.Resources:
- Feedback discussion where we are gathering feedback about the new APIs.
- Environment API PR where the new APIs were implemented and reviewed.
DevEnvironment Communication Levels
Since environments may run in different runtimes, communication against the environment may have constraints depending on the runtime. To allow frameworks to write runtime agnostic code easily, the Environment API provides three kinds of communication levels.RunnableDevEnvironment
RunnableDevEnvironment is an environment that can communicate arbitrary values. The implicit ssr environment and other non-client environments use a RunnableDevEnvironment by default during dev.
While this requires the runtime to be the same with the one the Vite server is running in, this works similarly with ssrLoadModule and allows frameworks to migrate and enable HMR for their SSR dev story. You can guard any runnable environment with an isRunnableDevEnvironment function.
SSR Setup Example
Given a Vite server configured in middleware mode as described by the SSR setup guide, let’s implement the SSR middleware using the environment API. Remember that it doesn’t have to be calledssr, so we’ll name it server in this example. Error handling is omitted.
RunnableDevEnvironment), you should add import.meta.hot.accept() in your server entry file for optimal behavior. Without this, server file changes will invalidate the entire server module graph:
src/entry-server.js
FetchableDevEnvironment
We are looking for feedback on the
FetchableDevEnvironment proposal.FetchableDevEnvironment is an environment that can communicate with its runtime via the Fetch API interface. Since the RunnableDevEnvironment is only possible to implement in a limited set of runtimes, we recommend to use the FetchableDevEnvironment instead of the RunnableDevEnvironment.
This environment provides a standardized way of handling requests via the handleRequest method:
Raw DevEnvironment
If the environment does not implement theRunnableDevEnvironment or FetchableDevEnvironment interfaces, you need to set up the communication manually.
Using Virtual Modules
If your code can run in the same runtime as the user modules (i.e., it does not rely on Node.js-specific APIs), you can use a virtual module. This approach eliminates the need to access the value from the code using Vite’s APIs.virtual:entrypoint
./entrypoint.js
transformIndexHtml on the user module, the following plugin can be used:
Using hot.send for Communication
If your code requires Node.js APIs, you can usehot.send to communicate with the code that uses Vite’s APIs from the user modules. However, be aware that this approach may not work the same way after the build process.
virtual:entrypoint
./entrypoint.js
Environments During Build
In the CLI, callingvite build and vite build --ssr will still build the client only and ssr only environments for backward compatibility.
When builder option is not undefined (or when calling vite build --app), vite build will opt-in into building the entire app instead. This would later on become the default in a future major. A ViteBuilder instance will be created (build-time equivalent to a ViteDevServer) to build all configured environments for production.
By default the build of environments is run in series respecting the order of the environments record. A framework or user can further configure how the environments are built using builder.buildApp option:
vite.config.js
buildApp hook. Order 'pre' and null are executed before the configured builder.buildApp, and order 'post' hooks are executed after it. environment.isBuilt can be used to check if an environment has already being build.
ObjectHook
Build all environments.Kind:
async, sequentialExperimentalEnvironment Agnostic Code
Most of the time, the currentenvironment instance will be available as part of the context of the code being run so the need to access them through server.environments should be rare.
For example, inside plugin hooks the environment is exposed as part of the PluginContext, so it can be accessed using this.environment. See Environment Plugins to learn about how to build environment aware plugins.