Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". This guide describes a revised API, renamed to Environment API. This API will be released in Vite 6 as experimental. You can already test it in the latest `vite@6.0.0-beta.x` version.
Resources:
- [Feedback discussion](https://github.com/vitejs/vite/discussions/16358) where we are gathering feedback about the new APIs.
- [Environment API PR](https://github.com/vitejs/vite/pull/16471) where the new API were implemented and reviewed.
Please share with us your feedback as you test the proposal.
:::
## Accessing the environments
During dev, the available environments in a dev server can be accessed using `server.environments`:
```js
// create the server, or get it from the configureServer hook
const server = await createServer(/* options */)
const environment = server.environments.client
environment.transformRequest(url)
console.log(server.environments.ssr.moduleGraph)
```
You can also access the current environment from plugins. See the [Environment API for Plugins](./api-environment-plugins.md#accessing-the-current-environment-in-hooks) for more details.
## `DevEnvironment` class
During dev, each environment is an instance of the `DevEnvironment` class:
```ts
class DevEnvironment {
/**
* Unique identifier for the environment in a Vite server.
* By default Vite exposes 'client' and 'ssr' environments.
*/
name: string
/**
* Communication channel to send and receive messages from the
* associated module runner in the target runtime.
*/
hot: HotChannel | null
/**
* Graph of module nodes, with the imported relationship between
* processed modules and the cached result of the processed code.
*/
moduleGraph: EnvironmentModuleGraph
/**
* Resolved plugins for this environment, including the ones
* created using the per-environment `create` hook
*/
plugins: Plugin[]
/**
* Allows to resolve, load, and transform code through the
* environment plugins pipeline
*/
pluginContainer: EnvironmentPluginContainer
/**
* Resolved config options for this environment. Options at the server
* global scope are taken as defaults for all environments, and can
* be overridden (resolve conditions, external, optimizedDeps)
An environment instance in the Vite server lets you process a URL using the `environment.transformRequest(url)` method. This function will use the plugin pipeline to resolve the `url` to a module `id`, load it (reading the file from the file system or through a plugin that implements a virtual module), and then transform the code. While transforming the module, imports and other metadata will be recorded in the environment module graph by creating or updating the corresponding module node. When processing is done, the transform result is also stored in the module.
:::info transformRequest naming
We are using `transformRequest(url)` and `warmupRequest(url)` in the current version of this proposal so it is easier to discuss and understand for users used to Vite's current API. Before releasing, we can take the opportunity to review these names too. For example, it could be named `environment.processModule(url)` or `environment.loadModule(url)` taking a page from Rollup's `context.load(id)` in plugin hooks. For the moment, we think keeping the current names and delaying this discussion is better.
:::
## Separate module graphs
Each environment has an isolated module graph. All module graphs have the same signature, so generic algorithms can be implemented to crawl or query the graph without depending on the environment. `hotUpdate` is a good example. When a file is modified, the module graph of each environment will be used to discover the affected modules and perform HMR for each environment independently.
::: info
Vite v5 had a mixed Client and SSR module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the Client, SSR, or both environments. Module nodes have some properties prefixed, like `clientImportedModules` and `ssrImportedModules` (and `importedModules` that returns the union of both). `importers` contains all importers from both the Client and SSR environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. A backward compatibility layer allows the ecosystem to migrate from the deprecated `server.moduleGraph`.
:::
Each module is represented by a `EnvironmentModuleNode` instance. Modules may be registered in the graph without yet being processed (`transformResult` would be `null` in that case). `importers` and `importedModules` are also updated after the module is processed.
```ts
class EnvironmentModuleNode {
environment: string
url: string
id: string | null = null
file: string | null = null
type: 'js' | 'css'
importers = new Set<EnvironmentModuleNode>()
importedModules = new Set<EnvironmentModuleNode>()