Environment Factories
Environment factories are intended to be implemented by Environment providers like Cloudflare, and not by end users. Environment factories return aEnvironmentOptions for the most common case of using the target runtime for both dev and build environments.
The default environment options can also be set so the user doesn’t need to do it.
Usage in Config
Then the config file can be written as:Creating a New Environment Factory
A Vite dev server exposes two environments by default:- A
clientenvironment (browser environment by default) - An
ssrenvironment (runs in the same Node runtime as the Vite server by default)
/@vite/client to client apps. The SSR environment runs in the same Node runtime as the Vite server by default and allows application servers to be used to render requests during dev with full HMR support.
Module Processing and Execution
The transformed source code is called a module, and the relationships between the modules processed in each environment are kept in a module graph. The transformed code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated in the runtime, its imported modules will be requested triggering the processing of a section of the module graph.Module Runners
A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different fromserver.ssrLoadModule because the runner implementation is decoupled from the server.
This allows library and framework authors to implement their layer of communication between the Vite server and the runner:
- The browser communicates with its corresponding environment using the server WebSocket and through HTTP requests
- The Node Module runner can directly do function calls to process modules as it is running in the same process
- Other environments could run modules connecting to a JS runtime like workerd, or a Worker Thread as Vitest does
Creating Custom Environments
One of the goals of this feature is to provide a customizable API to process and run code. Users can create new environment factories using the exposed primitives.There are multiple communication levels for the
DevEnvironment. To make it easier for frameworks to write runtime agnostic code, we recommend to implement the most flexible communication level possible.ModuleRunner
A module runner is instantiated in the target runtime. All APIs in this section are imported fromvite/module-runner unless stated otherwise. This export entry point is kept as lightweight as possible, only exporting the minimal needed to create module runners.
Type Signature
Constructor
Configuration options for the module runner
Module evaluator responsible for executing the code. Vite exports
ESModulesEvaluator which uses new AsyncFunction to evaluate code.Debugger instance for debugging module execution
Methods
Execute a module by URL. Accepts file path, server path, or id relative to the root.
Clear all caches including HMR listeners
Clear all caches, remove all HMR listeners, reset sourcemap support. This method doesn’t stop the HMR connection.
Returns
true if the runner has been closed by calling close()Example Usage
The module evaluator in
ModuleRunner is responsible for executing the code. You can provide your own implementation if your JavaScript runtime doesn’t support unsafe evaluation.When Vite server triggers full-reload HMR event, all affected modules will be re-executed. Be aware that Module Runner doesn’t update exports object when this happens (it overrides it), you would need to run import or get the module from evaluatedModules again if you rely on having the latest exports object.ModuleRunnerOptions
Properties
A set of methods to communicate with the server
Configure how source maps are resolved. Prefers
node if process.setSourceMapsEnabled is available. Otherwise it will use prepareStackTrace by default which overrides Error.prepareStackTrace method. You can provide an object to configure how file contents and source maps are resolved for files that were not processed by Vite.Disable HMR or configure HMR options
Custom module cache. If not provided, it creates a separate module cache for each module runner instance.
ModuleEvaluator
The module evaluator interface for executing transformed code.Properties
Number of prefixed lines in the transformed code
Methods
Evaluate code that was transformed by Vite
context: Function contextcode: Transformed codeid: ID that was used to fetch the module
Evaluate externalized module
file: File URL to the external module
ESModulesEvaluator that implements this interface by default. It uses new AsyncFunction to evaluate code, so if the code has inlined source map it should contain an offset of 2 lines to accommodate for new lines added.
This is done automatically by the ESModulesEvaluator. Custom evaluators will not add additional lines.
ModuleRunnerTransport
Transport object that communicates with the environment via an RPC or by directly calling the function.Properties and Methods
Connect to the environment and register message handlers
Disconnect from the environment
Send data to the environment (required if
invoke is not implemented)Invoke a method on the environment and get the result. If not implemented, Vite will construct it internally using
send and connect.Timeout in milliseconds for invoke calls
Worker Thread Example
You need to couple the transport with theHotChannel instance on the server. Here’s an example where module runner is created in the worker thread:
HTTP Request Example
A different example using an HTTP request to communicate between the runner and the server:handleInvoke method in the NormalizedHotChannel can be used:
For HMR support,
send and connect methods are required. The send method is usually called when the custom event is triggered (like, import.meta.hot.send("my-event")).Vite exports createServerHotChannel from the main entry point to support HMR during Vite SSR.