From 2822dd3732efbcd4573b88c522b3d25287050bf2 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 11:52:07 +0100 Subject: [PATCH 01/41] docs: Vite Environment API --- docs/.vitepress/config.ts | 4 + docs/guide/api-vite-environment.md | 529 +++++++++++++++++++++++++++++ docs/images/vite-environments.svg | 40 +++ 3 files changed, 573 insertions(+) create mode 100644 docs/guide/api-vite-environment.md create mode 100644 docs/images/vite-environments.svg diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index ad88cf1e2618dc..a2a6351016547f 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -275,6 +275,10 @@ export default defineConfig({ text: 'JavaScript API', link: '/guide/api-javascript', }, + { + text: 'Vite Environment API', + link: '/guide/api-vite-environment', + }, { text: 'Vite Runtime API', link: '/guide/api-vite-runtime', diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md new file mode 100644 index 00000000000000..a0ba7fc06710d9 --- /dev/null +++ b/docs/guide/api-vite-environment.md @@ -0,0 +1,529 @@ +# Vite Environment API + +:::warning Low-level API +Inital work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environemnt API. It still remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +::: + +A single Vite dev server can be used to interact with different module excecution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load and process source code and is connected to a runtime were the code is executed. Some examples of environments are: browser, ssr, workerd, rsc. The transformed source code is called a module, and the relationship between the modules processed in a each environment are kept in a module graph. The code for these modules are sent to the runtimes associated to each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. + +A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime implementation is decoupled from the server. This allows library and framework authors to implement their own layer of communication between the Vite server and the runner. The browser communicates communicates with its corresponding environment using the server Web Socket and through HTTP requests. The SSR Module runner can directly do function calls to process modules. Other environments could run modules connecting to an edge runtime like workerd, or a Worker Thread in the same node process as Vitest does. + +All these environments share Vite's HTTP server, middlewares and Web Socket. The resolved config and plugins pipeline are also shared, but plugins can use `apply` so its hooks are only called for certain environments. The environment can also be accessed inside hooks for fine grained control. + +![Vite Environments](../images/vite-environments.svg) + +## Using environments in the Vite server + +A Vite dev server exposes two environments by default named `'browser'` and `'ssr'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The SSR environment runs in the same runtime as the Vite server (for example, in node) and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. + +The available environments can be accessed using the `server.environments` read only array: + +```js +server.environments.forEach((environment) => log(environment.name)) +``` + +Each environment can also be accessed through its name: + +```js +server.environment('browser').transformRequest(url) +``` + +An environment is an instance of the `ModuleExecutionEnvironment` class: + +```ts +class ModuleExecutionEnvironment { + /** + * Unique identifier for the environment in a Vite server. + * By default Vite exposes 'browser' and 'ssr' environments. + * The ecosystem has concensus on other environments, like 'workerd'. + */ + name: string + /** + * Communication channel to send and receive messages from the + * associated module runner in the target runtime. + */ + hot: HMRChannel | null + /** + * Graph of module nodes, with the imported relationship between + * processed modules and the cached result of the processed code. + */ + moduleGraph: ModuleGraph + /** + * Trigger the execution of a module using the associated module runner + * in the target runtime. + */ + run: ModuleRunFunction + /** + * Resolved config options for this environment. Options at the server + * global scope are taken as defaults for all enviroments, and can + * be overriden (resolve conditions, external, optimizedDeps) + */ + config: ResolvedEnvironmentConfig + + constructor({ name, hot, run, config }: ModuleEnvironmentOptions) + + /** + * Resolve the URL to an id, load it, and process the code using the + * plugins pipeline. The module graph is also updated. + */ + async transformRequest(url: string) + + /** + * Register a request to be processed with low priority. This is useful + * to avoid waterfalls. The Vite server has information about the imported + * modules by other requests, so it can warmup the module graph so the + * modules are already processed when they are requested. + */ + async warmupRequest(url: string) + + /** + * Fetch information about a module from the module runner without running it. + */ + async fetch(url: string) +} +``` + +An environment instance in the Vite server let's 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 othe 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. + +But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, that ends up handled by the Transform Middleware by calling `server.environment('browser').transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. + +:::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. +::: + +For the default SSR environment, Vite creates a module runner that implements evaluation using `new AsyncFunction` running in the same runtime as the server. This runner is an instance of `ModuleRunner` that exposes: + +```ts +class ModuleRunner { + /** + * URL to execute. Accepts file path, server path, or id relative to the root. + * Returns an instantiated module (same as in ssrLoadModule) + */ + public async executeUrl(url: string): Promise> + /** + * Entry point URL to execute. Accepts file path, server path or id relative to the root. + * In the case of a full reload triggered by HMR, this is the module that will be reloaded. + * If this method is called multiple times, all entry points will be reloaded one at a time. + * Returns an instantiated module + */ + public async executeEntrypoint(url: string): Promise> + /** + * Other ModuleRunner methods... + */ +``` + +The SSR module runner instance is accessible through `server.ssrModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.ssrModuleRunner` and `server.environment('ssr')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. + +```js +app.use('*', async (req, res, next) => { + const url = req.originalUrl + + // 1. Read index.html + let template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8') + + // 2. Apply Vite HTML transforms. This injects the Vite HMR client, + // and also applies HTML transforms from Vite plugins, e.g. global + // preambles from @vitejs/plugin-react + template = await server.transformIndexHtml(url, template) + + // 3. Load the server entry. executeEntryPoint(url) automatically transforms + // ESM source code to be usable in Node.js! There is no bundling + // required, and provides full HMR support. + const { render } = await server.ssrModuleRunner.executeEntryPoint( + '/src/entry-server.js', + ) + + // 4. render the app HTML. This assumes entry-server.js's exported + // `render` function calls appropriate framework SSR APIs, + // e.g. ReactDOMServer.renderToString() + const appHtml = await render(url) + + // 5. Inject the app-rendered HTML into the template. + const html = template.replace(``, appHtml) + + // 6. Send the rendered HTML back. + res.status(200).set({ 'Content-Type': 'text/html' }).end(html) +}) +``` + +:::info ssrModuleRunner vs ssrEnvironment + +An alternative is to expose `server.ssrEnvironment` that implements both `ModuleExecutionEnvironment` and `ModuleRunner` as in this case they are both in the same runtime. In this case, the code above would be: + +```js +const { render } = await server.ssrEnvironment.executeEntryPoint( + '/src/entry-server.js', +) +``` + +This may be an interesting idea if we would like to move other SSR related methods like `ssrFixStacktrace` from the server to the `ssrEnvironment`. And we could also have `server.browserEnvironment` that extends the environment with browser specific functionality. + +For this proposal, `server.ssrModuleRunner` is used to highlight the separation between the Environment instance in the server and the module runner instance even if they are both available in the server for SSR. + +::: + +## Plugins and environments + +The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. + +### The `hotUpdate` hook + +- **Type:** `(ctx: HotContext) => Array | void | Promise | void>` +- **See also:** [HMR API](./api-hmr) + +The `hotUpdate` hook allows plugins to perform custom HMR update handling for a given environment. When a file changes, the HMR algorithm is run for each environment in serie according to the order in `server.environments`, so the `hotUpdate` hook will be called multiple times. The hook receives a context object with the following signature: + +```ts +interface HotContext { + file: string + timestamp: number + environment: ModuleExecutionEnvironment + modules: Array + read: () => string | Promise + server: ViteDevServer +} +``` + +- `environment` is the module execution environment where a file update is currently being processed. + +- `modules` is an array of modules in this environment that are affected by the changed file. It's an array because a single file may map to multiple served modules (e.g. Vue SFCs). + +- `read` is an async read function that returns the content of the file. This is provided because on some systems, the file change callback may fire too fast before the editor finishes updating the file and direct `fs.readFile` will return empty content. The read function passed in normalizes this behavior. + +The hook can choose to: + +- Filter and narrow down the affected module list so that the HMR is more accurate. + +- Return an empty array and perform a full reload: + + ```js + hotUpdate({ environment, modules, timestamp }) { + if (environment.name !== 'browser') + return + + environment.hot.send({ type: 'full-reload' }) + // Invalidate modules manually + const invalidatedModules = new Set() + for (const mod of modules) { + environment.moduleGraph.invalidateModule( + mod, + invalidatedModules, + timestamp, + true + ) + } + return [] + } + ``` + +- Return an empty array and perform complete custom HMR handling by sending custom events to the client: + + ```js + hotUpdate({ environment }) { + if (environment.name !== 'browser') + return + + environment.hot.send({ + type: 'custom', + event: 'special-update', + data: {} + }) + return [] + } + ``` + + Client code should register corresponding handler using the [HMR API](./api-hmr) (this could be injected by the same plugin's `transform` hook): + + ```js + if (import.meta.hot) { + import.meta.hot.on('special-update', (data) => { + // perform custom update + }) + } + ``` + +### Using `apply` + +In the examples of the previous section, we used a guard in the `hotUpdate` hook to only process updates from the browser environment. If a plugin is specific to only some of the available environments, `apply` can be used to avoid guarding each hook and improve performance. + +```js +function ssrOnlyPlugin() { + return { + name: 'ssr-only-plugin', + apply({ environment }) => environment.name === 'ssr', + // unguarded hooks... + } +} +``` + +### Accessing the current environment in hooks + +The `environment` instance is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. It can also be accessed using the plugin hook context by `this.environment`. + +A plugin could use the `environment` instance to: + +- Only apply logic for certain environments. +- Change the way they work depending the configuration for the environment, that can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. + +## Environment Configuration + +All environments share the Vite server configuration, but there are certain options that can be overriden per environment. + +```js +export default { + resolve: { + conditions: [] // shared by all environments + }, + environment: { + browser: { + resolve: { + conditions: [] // override for the browser environment + } + } + ssr: { + optimizeDeps: {} // override for the ssr environment + }, + workerd: { + noExternal: true // override for a third party environment + } + } +} +``` + +The subset of options that can be overriden are resolved and are available at `environment.config`. + +:::info What options can be overriden? + +Vite has already allowed defining some config for the [SSR environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overriden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. + +We could discuss what other options we should allow to be overriden, although maybe it is better to add them when there are requested by users later on. Some examples: `define`, `resolve.alias`, `resolve.dedupe`, `resolve.mainFields`, `resolve.extensions`. + +::: + +## Registering environments + +There is a new plugin hook called `registerEnvironment` that is called after `configResolved`: + +```js +function workedPlugin() { + return { + name: 'vite-plugin-workerd', + registerEnvironment(environments) { + const workedEnvironment = new WorkerdEnvironment() + // This environment has 'workerd' as its name, a convention agreed upon by the ecosystem + // connect workerdEnviroment logic to its associated workerd module runner + return [...environments, workedEnvironment] + }, + } +} +``` + +The environment will be accesible in middlewares or plugin hooks through `server.environment('workerd')`. + +## Creating new environments + +One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and ssr environments out of the box, but users can build new environments using the exposed primitives. + +```ts +import { createModuleExectutionEnvironment } from 'vite' + +const environment = createModuleExecutionEnvironment({ + name: 'workerd', + hot: null, + config: { + resolve: { conditions: ['custom'] } + }, + run(url) { + return rpc().runModule(url) + } +}) => ViteModuleExecutionEnvironment +``` + +## `ModuleRunner` + +A module runner is instantiated in the target runtime. All APIs in the next section are imported from `vite/environment` unless stated otherwise. This export entry point is kept as lightweight as possible, only exporting the minimal needed to create runners in the + +**Type Signature:** + +```ts +export class ModuleRunner { + constructor( + public options: ModuleRunnerOptions, + public evaluator: ModuleEvaluator, + private debug?: ModuleRunnerDebugger, + ) {} + /** + * URL to execute. Accepts file path, server path, or id relative to the root. + */ + public async executeUrl(url: string): Promise + /** + * Entry point URL to execute. Accepts file path, server path or id relative to the root. + * In the case of a full reload triggered by HMR, this is the module that will be reloaded. + * If this method is called multiple times, all entry points will be reloaded one at a time. + */ + public async executeEntrypoint(url: string): Promise + /** + * Clear all caches including HMR listeners. + */ + public clearCache(): void + /** + * Clears all caches, removes all HMR listeners, and resets source map support. + * This method doesn't stop the HMR connection. + */ + public async destroy(): Promise + /** + * Returns `true` if the runtime has been destroyed by calling `destroy()` method. + */ + public isDestroyed(): boolean +} +``` + +The module evaluator in `ModuleRunner` is responsible for executing the code. Vite exports `ESModulesEvaluator` out of the box, it uses `new AsyncFunction` to evaluate the code. You can provide your own implementation if your JavaScript runtime doesn't support unsafe evaluation. + +The two main methods that a module runner exposes are `executeUrl` and `executeEntrypoint`. The only difference between them is that all modules executed by `executeEntrypoint` will be reexecuted if HMR triggers `full-reload` event. Be aware that Vite module runners don't update the `exports` object when this happens, and instead it overrides it. You would need to run `executeUrl` or get the module from the `moduleCache` again if you rely on having the latest `exports` object. + +**Example Usage:** + +```js +import { ModuleRunner, ESModulesEvaluator } from 'vite/environment' +import { root, fetchModule } from './rpc-implementation.js' + +const moduleRunner = new ModuleRunner( + { + root, + fetchModule, + // you can also provide hmr.connection to support HMR + }, + new ESModulesEvaluator(), +) + +await moduleRunner.executeEntrypoint('/src/entry-point.js') +``` + +## `ModuleRunnerOptions` + +```ts +export interface ModuleRunnerOptions { + /** + * Root of the project + */ + root: string + /** + * A method to get the information about the module. + */ + fetchModule: FetchFunction + /** + * 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. + */ + sourcemapInterceptor?: + | false + | 'node' + | 'prepareStackTrace' + | InterceptorOptions + /** + * Disable HMR or configure HMR options. + */ + hmr?: + | false + | { + /** + * Configure how HMR communicates between the client and the server. + */ + connection: HMRRuntimeConnection + /** + * Configure HMR logger. + */ + logger?: false | HMRLogger + } + /** + * Custom module cache. If not provided, it creates a separate module cache for each ViteRuntime instance. + */ + moduleCache?: ModuleCacheMap +} +``` + +## `ModuleEvaluator` + +**Type Signature:** + +```ts +export interface ModuleEvaluator { + /** + * Evaluate code that was transformed by Vite. + * @param context Function context + * @param code Transformed code + * @param id ID that was used to fetch the module + */ + evaluateModule( + context: ModuleRunnerContext, + code: string, + id: string, + ): Promise + /** + * evaluate externalized module. + * @param file File URL to the external module + */ + evaluateExternalModule(file: string): Promise +} +``` + +Vite exports `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](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically in the server SSR environment. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. + +## HMRModuleRunnerConnection + +**Type Signature:** + +```ts +export interface HMRModuleRunnerConnection { + /** + * Checked before sending messages to the client. + */ + isReady(): boolean + /** + * Send message to the client. + */ + send(message: string): void + /** + * Configure how HMR is handled when this connection triggers an update. + * This method expects that connection will start listening for HMR updates and call this callback when it's received. + */ + onUpdate(callback: (payload: HMRPayload) => void): void +} +``` + +This interface defines how HMR communication is established. Vite exports `ServerHMRConnector` from the main entry point to support HMR during Vite SSR. The `isReady` and `send` methods are usually called when the custom event is triggered (like, `import.meta.hot.send("my-event")`). + +`onUpdate` is called only once when the new runtime is initiated. It passed down a method that should be called when connection triggers the HMR event. The implementation depends on the type of connection (as an example, it can be `WebSocket`/`EventEmitter`/`MessageChannel`), but it usually looks something like this: + +```js +function onUpdate(callback) { + this.connection.on('hmr', (event) => callback(event.data)) +} +``` + +The callback is queued and it will wait for the current update to be resolved before processing the next update. Unlike the browser implementation, HMR updates in Vite Runtime wait until all listeners (like, `vite:beforeUpdate`/`vite:beforeFullReload`) are finished before updating the modules. + +## Backward Compatibility + +The current Vite server API will be deprecated but keep working during the next major. + +- `server.transformRequest(url)`
-> `server.environment('browser').transformRequest(url)` +- `server.transformRequest(url, { ssr: true })`
-> `server.environment('ssr').tranformRequest(url)` +- `server.warmupRequest(url)`
-> `server.environment('browser').warmupRequest(url)` +- `server.ssrLoadModule(url)`
-> `server.ssrModuleRunner.executeEntryPoint(url)` +- `server.moduleGraph`
-> `server.environment(name).moduleGraph` +- `handleHotUpdate`
-> `hotUpdate` + +Maybe we could also have: + +- `server.open(url)`
-> `server.environment('browser').run(url)` + +The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt in until then when releasing the API as experimental in Vite 5.2. + +## Open Questions + +There are some open questions and alternative as info boxes interlined in the guide. + +Names for concepts and the API are the best we could currently find, what we should keep discussing before releasing if we end up adopting this proposal. diff --git a/docs/images/vite-environments.svg b/docs/images/vite-environments.svg new file mode 100644 index 00000000000000..faea48b0c4217f --- /dev/null +++ b/docs/images/vite-environments.svg @@ -0,0 +1,40 @@ +Vite Dev ServerVite Dev ServerBrowser  +EnvironmentBrowser  +EnvironmentSSR  +EnvironmentSSR  +EnvironmentBrowser  +RuntimeBrowser  +RuntimeWorkerd  + RuntimeWorkerd  + RuntimeWorkerd  +EnvironmentWorkerd  +EnvironmentNode-Compatible  +RuntimeNode-Compatible  +RuntimeBrowser  +Module  +RunnerBrowser  +Module  +RunnerSSR  +Module  +RunnerSSR  +Module  +RunnerWorkerd  +Module  +RunnerWorkerd  +Module  +RunnerVitest JSDOM  +EnvironmentVitest JSDOM  +EnvironmentWorker  +Thread  +Module  +RunnerWorker  +Thread  +Module  +RunnerHTTP ServerHTTP ServerMiddlewaresMiddlewaresPlugins PipelinePlugins PipelineWeb SocketWeb Socket \ No newline at end of file From f44361a5b7bc7248ff3c979cde962a2fc9f1dee9 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 12:20:42 +0100 Subject: [PATCH 02/41] chore: add server param to registerEnvironment hook --- docs/guide/api-vite-environment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index a0ba7fc06710d9..e95a62bd1b3de3 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -308,8 +308,8 @@ There is a new plugin hook called `registerEnvironment` that is called after `co function workedPlugin() { return { name: 'vite-plugin-workerd', - registerEnvironment(environments) { - const workedEnvironment = new WorkerdEnvironment() + registerEnvironment(server, environments) { + const workedEnvironment = new WorkerdEnvironment(server) // This environment has 'workerd' as its name, a convention agreed upon by the ecosystem // connect workerdEnviroment logic to its associated workerd module runner return [...environments, workedEnvironment] From 34bf32ab8d1277b1d8a1b04709afe7c5b0edfc2a Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 12:21:21 +0100 Subject: [PATCH 03/41] chore: use push in registerEnvironment hook --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index e95a62bd1b3de3..45896d0e9316d3 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -312,7 +312,7 @@ function workedPlugin() { const workedEnvironment = new WorkerdEnvironment(server) // This environment has 'workerd' as its name, a convention agreed upon by the ecosystem // connect workerdEnviroment logic to its associated workerd module runner - return [...environments, workedEnvironment] + environments.push(workedEnvironment) }, } } From c0ba020cbef84f39fc76c94c5409dc99f641f060 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 12:38:10 +0100 Subject: [PATCH 04/41] chore: use string for environment in hooks --- docs/guide/api-vite-environment.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 45896d0e9316d3..bfc75f9d987722 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -198,14 +198,14 @@ The hook can choose to: ```js hotUpdate({ environment, modules, timestamp }) { - if (environment.name !== 'browser') + if (environment !== 'browser') return - environment.hot.send({ type: 'full-reload' }) + server.environment(environment).hot.send({ type: 'full-reload' }) // Invalidate modules manually const invalidatedModules = new Set() for (const mod of modules) { - environment.moduleGraph.invalidateModule( + server.environment(environment).moduleGraph.invalidateModule( mod, invalidatedModules, timestamp, @@ -220,10 +220,10 @@ The hook can choose to: ```js hotUpdate({ environment }) { - if (environment.name !== 'browser') + if (environment !== 'browser') return - environment.hot.send({ + server.environment(environment).hot.send({ type: 'custom', event: 'special-update', data: {} @@ -250,7 +250,7 @@ In the examples of the previous section, we used a guard in the `hotUpdate` hook function ssrOnlyPlugin() { return { name: 'ssr-only-plugin', - apply({ environment }) => environment.name === 'ssr', + apply({ environment }) => environment === 'ssr', // unguarded hooks... } } From 7e7df983e4ad5a6856a3bb44a05ac2d1416dd074 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 12:39:33 +0100 Subject: [PATCH 05/41] chore: vite/environment entry point renamed to /module-runner --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index bfc75f9d987722..a884cee237e24d 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -341,7 +341,7 @@ const environment = createModuleExecutionEnvironment({ ## `ModuleRunner` -A module runner is instantiated in the target runtime. All APIs in the next section are imported from `vite/environment` unless stated otherwise. This export entry point is kept as lightweight as possible, only exporting the minimal needed to create runners in the +A module runner is instantiated in the target runtime. All APIs in the next section are imported from `vite/module-runner` unless stated otherwise. This export entry point is kept as lightweight as possible, only exporting the minimal needed to create runners in the **Type Signature:** From 54fd605594d21be1ea84504699f7ae963c412efb Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 14:22:00 +0100 Subject: [PATCH 06/41] chore: environment is a string in HotContext --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index a884cee237e24d..a2af8fb4344029 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -177,7 +177,7 @@ The `hotUpdate` hook allows plugins to perform custom HMR update handling for a interface HotContext { file: string timestamp: number - environment: ModuleExecutionEnvironment + environment: string modules: Array read: () => string | Promise server: ViteDevServer From bb9354d5d602c79b7f7b087db406ac6b08ceced5 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 14:22:40 +0100 Subject: [PATCH 07/41] chore: add note about string vs object environment in hooks --- docs/guide/api-vite-environment.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index a2af8fb4344029..b165005e5d2494 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -265,6 +265,12 @@ A plugin could use the `environment` instance to: - Only apply logic for certain environments. - Change the way they work depending the configuration for the environment, that can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. +:::info environment in hooks + +We could also pass an environment object that has `{ name, config }`. In a previous iteration the environment instance was passed directly as a parameter but we also need to pass the `environment` name during build time to hooks. + +::: + ## Environment Configuration All environments share the Vite server configuration, but there are certain options that can be overriden per environment. From cae926b2ee235ff37f97119dfbe30da4ab270b48 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 14:23:09 +0100 Subject: [PATCH 08/41] chore: separate module graphs section --- docs/guide/api-vite-environment.md | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index b165005e5d2494..89c4d47ae2bbfa 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -306,6 +306,98 @@ We could discuss what other options we should allow to be overriden, although ma ::: +## Separate module graphs + +Vite currently has a mixed browser and ssr module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also have `transformResult` and `ssrTransformResult`. + +In this proposal, each environment has its own module graph (and a backward compatibility layer will be implemented to give time to the ecosystem to migrate). 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 discovered the affected modules and perform HMR for each environment independendently. + +Each module is represented by a `ModuleNode` 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 ModuleNode { + environment: string + + url: string + id: string | null = null + file: string | null = null + + type: 'js' | 'css' + + importers = new Set() + importedModules = new Set() + importedBindings: Map> | null = null + + info?: ModuleInfo + meta?: Record + transformResult: TransformResult | null = null + + acceptedHmrDeps = new Set() + acceptedHmrExports: Set | null = null + isSelfAccepting?: boolean + lastHMRTimestamp = 0 + lastInvalidationTimestamp = 0 +} +``` + +`environment.moduleGraph` is an instance of `ModuleGraph`: + +```ts +export class ModuleGraph { + environment: string + + urlToModuleMap = new Map() + idToModuleMap = new Map() + etagToModuleMap = new Map() + fileToModulesMap = new Map>() + + constructor( + environment: string, + resolveId: (url: string) => Promise, + ) + + async getModuleByUrl(rawUrl: string): Promise + + getModulesByFile(file: string): Set | undefined + + onFileChange(file: string): void + + invalidateModule( + mod: ModuleNode, + seen: Set = new Set(), + timestamp: number = Date.now(), + isHmr: boolean = false, + ): void + + invalidateAll(): void + + async updateModuleInfo( + mod: ModuleNode, + importedModules: Set, + importedBindings: Map> | null, + acceptedModules: Set, + acceptedExports: Set | null, + isSelfAccepting: boolean, + ): Promise | undefined> + + async ensureEntryFromUrl( + rawUrl: string, + setIsSelfAccepting = true, + ): Promise + + createFileOnlyEntry(file: string): ModuleNode + + async resolveUrl(url: string): Promise + + updateModuleTransformResult( + mod: ModuleNode, + result: TransformResult | null, + ): void + + getModuleByEtag(etag: string): ModuleNode | undefined +} +``` + ## Registering environments There is a new plugin hook called `registerEnvironment` that is called after `configResolved`: From 27f8c1259110adc184e97f645a21ec3b5275d064 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 14:23:30 +0100 Subject: [PATCH 09/41] chore: environments during build section --- docs/guide/api-vite-environment.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 89c4d47ae2bbfa..444a10bfd91edb 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -603,6 +603,18 @@ function onUpdate(callback) { The callback is queued and it will wait for the current update to be resolved before processing the next update. Unlike the browser implementation, HMR updates in Vite Runtime wait until all listeners (like, `vite:beforeUpdate`/`vite:beforeFullReload`) are finished before updating the modules. +## Environments during build + +Plugin hooks also receive the environment name during build. This replaces the `ssr` boolean we have been passing them so far. + +The Vite CLI would aslo be updated from `vite build --ssr` to `vite build --environment=ssr`. Applications can then call build for each environment (for example `vite build --environment=workerd`). + +In a future stage, or as part of this proposal, we could also review or stance on vite build being a simple wrapper around rollup. Instead, now that we have a proper environment concept, vite build could create a `ViteBuilder` that has knowledge of all the configured environments and build them all with a single call. This has been requested many times by framework authors that use the "Framework as a plugin" scheme. Right now they end up triggering the SSR build when the `buildEnd` hook for the browser build is called. + +In its simpler form, the vite builder could call each build in series as defined by `config.environments` order (or by a new `config.build.environments` order). This should cover most current use cases out of the box, given that most frameworks build the client first and then SSR (as they use the client manifest). + +It is an interesting design space to explore because it could make build and dev work in a more uniform way. For example, Vite Builder could also only load the config file once and do the overrides for each environment in the exact same way as it is done during dev. And there could also be a single plugin pipeline, if we would like plugins to share state directly between the environments (as it happens during dev already). + ## Backward Compatibility The current Vite server API will be deprecated but keep working during the next major. From 9712649e01380784674a7a4f06c0c8c9d7daf2e7 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 14:41:09 +0100 Subject: [PATCH 10/41] chore: use table for back compat before/after --- docs/guide/api-vite-environment.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 444a10bfd91edb..d105381e820b9d 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -619,16 +619,17 @@ It is an interesting design space to explore because it could make build and dev The current Vite server API will be deprecated but keep working during the next major. -- `server.transformRequest(url)`
-> `server.environment('browser').transformRequest(url)` -- `server.transformRequest(url, { ssr: true })`
-> `server.environment('ssr').tranformRequest(url)` -- `server.warmupRequest(url)`
-> `server.environment('browser').warmupRequest(url)` -- `server.ssrLoadModule(url)`
-> `server.ssrModuleRunner.executeEntryPoint(url)` -- `server.moduleGraph`
-> `server.environment(name).moduleGraph` -- `handleHotUpdate`
-> `hotUpdate` - -Maybe we could also have: - -- `server.open(url)`
-> `server.environment('browser').run(url)` +| Before | After | +| :-------------------------------------------: | :---------------------------------------------------: | +| `server.transformRequest(url)` | `server.environment('browser').transformRequest(url)` | +| `server.transformRequest(url, { ssr: true })` | `server.environment('ssr').tranformRequest(url)` | +| `server.warmupRequest(url)` | `server.environment('browser').warmupRequest(url)` | +| `server.ssrLoadModule(url)` | `server.ssrModuleRunner.executeEntryPoint(url)` | +| `server.moduleGraph` | `server.environment(name).moduleGraph` | +| `handleHotUpdate` | `hotUpdate` | +| `server.open(url)` | `server.environment('browser').run(url)` | + +The last one is just an idea. We may want to keep `server.open(url)` around. The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt in until then when releasing the API as experimental in Vite 5.2. From 62be6b8117af6387902eb04bb17a597e3f75a157 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 15:56:48 +0100 Subject: [PATCH 11/41] chore: update environment instance vs string (again) --- docs/guide/api-vite-environment.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index d105381e820b9d..db2c4ee5677c9d 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -201,11 +201,13 @@ The hook can choose to: if (environment !== 'browser') return - server.environment(environment).hot.send({ type: 'full-reload' }) + const serverEnvironment = server.environment(environment) + + serverEnvironment.hot.send({ type: 'full-reload' }) // Invalidate modules manually const invalidatedModules = new Set() for (const mod of modules) { - server.environment(environment).moduleGraph.invalidateModule( + serverEnvironment.moduleGraph.invalidateModule( mod, invalidatedModules, timestamp, @@ -258,7 +260,7 @@ function ssrOnlyPlugin() { ### Accessing the current environment in hooks -The `environment` instance is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. It can also be accessed using the plugin hook context by `this.environment`. +The `environment` name is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. A plugin could use the `environment` instance to: @@ -267,8 +269,24 @@ A plugin could use the `environment` instance to: :::info environment in hooks +Using the `environment` string in the hooks don't read that well. It isn't clear what should be the name used for a variable when there the environment is used in several places in the hook. It could probably be `serverEnvironment`: + +```js +const serverEnvironment = server.environment(environment) +if ( + serverEnvironment.config.noExternal === true || + serverEnvironment.moduleGraph.getModuleById(id) +) { + // ... +} +``` + We could also pass an environment object that has `{ name, config }`. In a previous iteration the environment instance was passed directly as a parameter but we also need to pass the `environment` name during build time to hooks. +Or we could pass to the hooks both `{ environmentName, serverEnvironment }` to avoid cluttering every hook with `const serverEnvironment = server.environment(environment)`. Check out the build section later on. If we explore having a `ViteBuilder` that is aware of environments (and can build them all). We could pass `{ environmentName, serverEnvironment, builderEnvironment }`. One of the instances will always be undefined in this case. I think this is more confortable to use compared to a single `{ environment: server environment | builder environment }` instance. + +We could also make the environment name or common environment object accesible using the plugin hook context with `this.serverEnvironment`. + ::: ## Environment Configuration From 7aa4039660f42f511e3b71b2bfe9b467d7bf4c5e Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 15:58:54 +0100 Subject: [PATCH 12/41] chore: add server param to ModuleExcecutionEnvironment. --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index db2c4ee5677c9d..1b1a39bfde89f7 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -60,7 +60,7 @@ class ModuleExecutionEnvironment { */ config: ResolvedEnvironmentConfig - constructor({ name, hot, run, config }: ModuleEnvironmentOptions) + constructor(server, { name, hot, run, config }: ModuleEnvironmentOptions) /** * Resolve the URL to an id, load it, and process the code using the From 8c452118c37b0391f5d935a1a0b0cda5a906deae Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 16:59:25 +0100 Subject: [PATCH 13/41] chore: improve diagram --- docs/images/vite-environments.svg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/images/vite-environments.svg b/docs/images/vite-environments.svg index faea48b0c4217f..38ceec80becc99 100644 --- a/docs/images/vite-environments.svg +++ b/docs/images/vite-environments.svg @@ -1,21 +1,21 @@ -Vite Dev ServerVite Dev ServerBrowser  EnvironmentBrowser  EnvironmentSSR  EnvironmentSSR  -EnvironmentBrowser  +EnvironmentBrowser  RuntimeBrowser  -RuntimeWorkerd  +RuntimeWorkerd   RuntimeWorkerd  - RuntimeWorkerd  + RuntimeWorkerd  EnvironmentWorkerd  -EnvironmentNode-Compatible  +EnvironmentNode-Compatible  RuntimeNode-Compatible  RuntimeBrowser  Module  @@ -37,4 +37,4 @@ RunnerWorker  Thread  Module  -RunnerHTTP ServerHTTP ServerMiddlewaresMiddlewaresPlugins PipelinePlugins PipelineWeb SocketWeb Socket \ No newline at end of file +RunnerHTTP ServerHTTP ServerMiddlewaresMiddlewaresPlugins PipelinePlugins PipelineWeb SocketWeb Socket \ No newline at end of file From ac81642fed7fa33e977c5603075b1f1e1b412533 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 22:22:35 +0100 Subject: [PATCH 14/41] chore: add naming alternatives --- docs/guide/api-vite-environment.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 1b1a39bfde89f7..3c0177873ca932 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -656,3 +656,19 @@ The `server.moduleGraph` will keep returning a mixed view of the browser and ssr There are some open questions and alternative as info boxes interlined in the guide. Names for concepts and the API are the best we could currently find, what we should keep discussing before releasing if we end up adopting this proposal. + +## Alternatives + +In the process of discussing this proposal, we analized other alternatives. Listing here some of them related to naming. + +### ModuleLoader vs Environment + +Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. And we could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=ssr` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seems like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. + +### Runtime vs Environment + +We also discussed naming runtime to the concept we call environment in this proposal. We decided to go with Environment because a Runtime referes to node, bun, deno, workerd, a browser. But we need to be able to define two different module excecution "environments" for the same runtime. For example SSR and RSC environments, both running in the same node runtime. + +### Server and Client + +We could also call `ModuleExecutionEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the http server, etc) and client is also used right now to refer to the browser (as in `clientImportedModules`). From 3f02bf76422bf326781e11aeea2e9305a74dedf4 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 23:00:01 +0100 Subject: [PATCH 15/41] chore: remove unneeded section --- docs/guide/api-vite-environment.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 3c0177873ca932..3d19ff07b04f49 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -651,15 +651,11 @@ The last one is just an idea. We may want to keep `server.open(url)` around. The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt in until then when releasing the API as experimental in Vite 5.2. -## Open Questions +## Open Questions and Alternatives There are some open questions and alternative as info boxes interlined in the guide. -Names for concepts and the API are the best we could currently find, what we should keep discussing before releasing if we end up adopting this proposal. - -## Alternatives - -In the process of discussing this proposal, we analized other alternatives. Listing here some of them related to naming. +Names for concepts and the API are the best we could currently find, what we should keep discussing before releasing if we end up adopting this proposal. Here are some of the alternative naming we discussed in the process of creating this proposal. ### ModuleLoader vs Environment From eff80caef363c231babf6f7d05173c7d789d2c45 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 4 Mar 2024 23:11:29 +0100 Subject: [PATCH 16/41] chore: fix typos --- docs/guide/api-vite-environment.md | 89 +++++++++++++++--------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 3d19ff07b04f49..6b094670022832 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -1,14 +1,14 @@ # Vite Environment API :::warning Low-level API -Inital work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environemnt API. It still remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +Initial work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environemnt API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. ::: -A single Vite dev server can be used to interact with different module excecution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load and process source code and is connected to a runtime were the code is executed. Some examples of environments are: browser, ssr, workerd, rsc. The transformed source code is called a module, and the relationship between the modules processed in a each environment are kept in a module graph. The code for these modules are sent to the runtimes associated to each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. +A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. Some examples of environments are browser, ssr, workerd, rsc. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. -A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime implementation is decoupled from the server. This allows library and framework authors to implement their own layer of communication between the Vite server and the runner. The browser communicates communicates with its corresponding environment using the server Web Socket and through HTTP requests. The SSR Module runner can directly do function calls to process modules. Other environments could run modules connecting to an edge runtime like workerd, or a Worker Thread in the same node process as Vitest does. +A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime 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 Web Socket and through HTTP requests. The SSR Module runner can directly do function calls to process modules. Other environments could run modules connecting to an edge runtime like workerd, or a Worker Thread in the same node process as Vitest does. -All these environments share Vite's HTTP server, middlewares and Web Socket. The resolved config and plugins pipeline are also shared, but plugins can use `apply` so its hooks are only called for certain environments. The environment can also be accessed inside hooks for fine grained control. +All these environments share Vite's HTTP server, middlewares, and Web Socket. The resolved config and plugins pipeline are also shared, but plugins can use `apply` so its hooks are only called for certain environments. The environment can also be accessed inside hooks for fine-grained control. ![Vite Environments](../images/vite-environments.svg) @@ -16,7 +16,7 @@ All these environments share Vite's HTTP server, middlewares and Web Socket. The A Vite dev server exposes two environments by default named `'browser'` and `'ssr'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The SSR environment runs in the same runtime as the Vite server (for example, in node) and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. -The available environments can be accessed using the `server.environments` read only array: +The available environments can be accessed using the `server.environments` read-only array: ```js server.environments.forEach((environment) => log(environment.name)) @@ -35,7 +35,7 @@ class ModuleExecutionEnvironment { /** * Unique identifier for the environment in a Vite server. * By default Vite exposes 'browser' and 'ssr' environments. - * The ecosystem has concensus on other environments, like 'workerd'. + * The ecosystem has consensus on other environments, like 'workerd'. */ name: string /** @@ -55,12 +55,15 @@ class ModuleExecutionEnvironment { run: ModuleRunFunction /** * Resolved config options for this environment. Options at the server - * global scope are taken as defaults for all enviroments, and can - * be overriden (resolve conditions, external, optimizedDeps) + * global scope are taken as defaults for all environments, and can + * be overridden (resolve conditions, external, optimizedDeps) */ config: ResolvedEnvironmentConfig - constructor(server, { name, hot, run, config }: ModuleEnvironmentOptions) + constructor( + server, + { name, hot, run, config }: ModuleExecutionEnvironmentOptions, + ) /** * Resolve the URL to an id, load it, and process the code using the @@ -83,9 +86,9 @@ class ModuleExecutionEnvironment { } ``` -An environment instance in the Vite server let's 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 othe 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. +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. -But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, that ends up handled by the Transform Middleware by calling `server.environment('browser').transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. +But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.environment('browser').transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. :::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. @@ -148,7 +151,7 @@ app.use('*', async (req, res, next) => { :::info ssrModuleRunner vs ssrEnvironment -An alternative is to expose `server.ssrEnvironment` that implements both `ModuleExecutionEnvironment` and `ModuleRunner` as in this case they are both in the same runtime. In this case, the code above would be: +An alternative is to expose `server.ssrEnvironment` that implements both `ModuleExecutionEnvironment` and `ModuleRunner` as in this case, they are both in the same runtime. In this case, the code above would be: ```js const { render } = await server.ssrEnvironment.executeEntryPoint( @@ -156,7 +159,7 @@ const { render } = await server.ssrEnvironment.executeEntryPoint( ) ``` -This may be an interesting idea if we would like to move other SSR related methods like `ssrFixStacktrace` from the server to the `ssrEnvironment`. And we could also have `server.browserEnvironment` that extends the environment with browser specific functionality. +This may be an interesting idea if we would like to move other SSR-related methods like `ssrFixStacktrace` from the server to the `ssrEnvironment`. And we could also have `server.browserEnvironment` that extends the environment with browser-specific functionality. For this proposal, `server.ssrModuleRunner` is used to highlight the separation between the Environment instance in the server and the module runner instance even if they are both available in the server for SSR. @@ -171,7 +174,7 @@ The Vite server has a shared plugin pipeline, but when a module is processed it - **Type:** `(ctx: HotContext) => Array | void | Promise | void>` - **See also:** [HMR API](./api-hmr) -The `hotUpdate` hook allows plugins to perform custom HMR update handling for a given environment. When a file changes, the HMR algorithm is run for each environment in serie according to the order in `server.environments`, so the `hotUpdate` hook will be called multiple times. The hook receives a context object with the following signature: +The `hotUpdate` hook allows plugins to perform custom HMR update handling for a given environment. When a file changes, the HMR algorithm is run for each environment in series according to the order in `server.environments`, so the `hotUpdate` hook will be called multiple times. The hook receives a context object with the following signature: ```ts interface HotContext { @@ -188,7 +191,7 @@ interface HotContext { - `modules` is an array of modules in this environment that are affected by the changed file. It's an array because a single file may map to multiple served modules (e.g. Vue SFCs). -- `read` is an async read function that returns the content of the file. This is provided because on some systems, the file change callback may fire too fast before the editor finishes updating the file and direct `fs.readFile` will return empty content. The read function passed in normalizes this behavior. +- `read` is an async read function that returns the content of the file. This is provided because, on some systems, the file change callback may fire too fast before the editor finishes updating the file, and direct `fs.readFile` will return empty content. The read function passed in normalizes this behavior. The hook can choose to: @@ -234,7 +237,7 @@ The hook can choose to: } ``` - Client code should register corresponding handler using the [HMR API](./api-hmr) (this could be injected by the same plugin's `transform` hook): + Client code should register the corresponding handler using the [HMR API](./api-hmr) (this could be injected by the same plugin's `transform` hook): ```js if (import.meta.hot) { @@ -265,11 +268,11 @@ The `environment` name is passed as a parameter to the `options` of `resolveId`, A plugin could use the `environment` instance to: - Only apply logic for certain environments. -- Change the way they work depending the configuration for the environment, that can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. +- Change the way they work depending on the configuration for the environment, which can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. :::info environment in hooks -Using the `environment` string in the hooks don't read that well. It isn't clear what should be the name used for a variable when there the environment is used in several places in the hook. It could probably be `serverEnvironment`: +Using the `environment` string in the hooks doesn't read that well. It isn't clear what should be the name used for a variable when the environment is used in several places in the hook. It could probably be `serverEnvironment`: ```js const serverEnvironment = server.environment(environment) @@ -281,17 +284,17 @@ if ( } ``` -We could also pass an environment object that has `{ name, config }`. In a previous iteration the environment instance was passed directly as a parameter but we also need to pass the `environment` name during build time to hooks. +We could also pass an environment object that has `{ name, config }`. In a previous iteration, the environment instance was passed directly as a parameter but we also need to pass the `environment` name during build time to hooks. -Or we could pass to the hooks both `{ environmentName, serverEnvironment }` to avoid cluttering every hook with `const serverEnvironment = server.environment(environment)`. Check out the build section later on. If we explore having a `ViteBuilder` that is aware of environments (and can build them all). We could pass `{ environmentName, serverEnvironment, builderEnvironment }`. One of the instances will always be undefined in this case. I think this is more confortable to use compared to a single `{ environment: server environment | builder environment }` instance. +Or we could pass to the hooks both `{ environmentName, serverEnvironment }` to avoid cluttering every hook with `const serverEnvironment = server.environment(environment)`. Check out the build section later on. If we explore having a `ViteBuilder` that is aware of environments (and can build them all). We could pass `{ environmentName, serverEnvironment, builderEnvironment }`. One of the instances will always be undefined in this case. I think this is more comfortable to use compared to a single `{ environment: server environment | builder environment }` instance. -We could also make the environment name or common environment object accesible using the plugin hook context with `this.serverEnvironment`. +We could also make the environment name or common environment object accessible using the plugin hook context with `this.serverEnvironment`. ::: ## Environment Configuration -All environments share the Vite server configuration, but there are certain options that can be overriden per environment. +All environments share the Vite server configuration, but certain options can be overridden per environment. ```js export default { @@ -308,27 +311,27 @@ export default { optimizeDeps: {} // override for the ssr environment }, workerd: { - noExternal: true // override for a third party environment + noExternal: true // override for a third-party environment } } } ``` -The subset of options that can be overriden are resolved and are available at `environment.config`. +The subset of options that can be overridden are resolved and are available at `environment.config`. -:::info What options can be overriden? +:::info What options can be overridden? -Vite has already allowed defining some config for the [SSR environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overriden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. +Vite has already allowed defining some config for the [SSR environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overridden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. -We could discuss what other options we should allow to be overriden, although maybe it is better to add them when there are requested by users later on. Some examples: `define`, `resolve.alias`, `resolve.dedupe`, `resolve.mainFields`, `resolve.extensions`. +We could discuss what other options we should allow to be overridden, although maybe it is better to add them when they are requested by users later on. Some examples: `define`, `resolve.alias`, `resolve.dedupe`, `resolve.mainFields`, `resolve.extensions`. ::: ## Separate module graphs -Vite currently has a mixed browser and ssr module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also have `transformResult` and `ssrTransformResult`. +Vite currently has a mixed browser and ssr module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. -In this proposal, each environment has its own module graph (and a backward compatibility layer will be implemented to give time to the ecosystem to migrate). 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 discovered the affected modules and perform HMR for each environment independendently. +In this proposal, each environment has its module graph (and a backward compatibility layer will be implemented to give time to the ecosystem to migrate). 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. Each module is represented by a `ModuleNode` 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. @@ -434,11 +437,11 @@ function workedPlugin() { } ``` -The environment will be accesible in middlewares or plugin hooks through `server.environment('workerd')`. +The environment will be accessible in middlewares or plugin hooks through `server.environment('workerd')`. ## Creating new environments -One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and ssr environments out of the box, but users can build new environments using the exposed primitives. +One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and SSR environments out of the box, but users can build new environments using the exposed primitives. ```ts import { createModuleExectutionEnvironment } from 'vite' @@ -496,7 +499,7 @@ export class ModuleRunner { The module evaluator in `ModuleRunner` is responsible for executing the code. Vite exports `ESModulesEvaluator` out of the box, it uses `new AsyncFunction` to evaluate the code. You can provide your own implementation if your JavaScript runtime doesn't support unsafe evaluation. -The two main methods that a module runner exposes are `executeUrl` and `executeEntrypoint`. The only difference between them is that all modules executed by `executeEntrypoint` will be reexecuted if HMR triggers `full-reload` event. Be aware that Vite module runners don't update the `exports` object when this happens, and instead it overrides it. You would need to run `executeUrl` or get the module from the `moduleCache` again if you rely on having the latest `exports` object. +The two main methods that a module runner exposes are `executeUrl` and `executeEntrypoint`. The only difference between them is that all modules executed by `executeEntrypoint` will be re-executed if HMR triggers `full-reload` event. Be aware that Vite module runners don't update the `exports` object when this happens, instead, it overrides it. You would need to run `executeUrl` or get the module from the `moduleCache` again if you rely on having the latest `exports` object. **Example Usage:** @@ -598,12 +601,12 @@ export interface HMRModuleRunnerConnection { */ isReady(): boolean /** - * Send message to the client. + * Send a message to the client. */ send(message: string): void /** * Configure how HMR is handled when this connection triggers an update. - * This method expects that connection will start listening for HMR updates and call this callback when it's received. + * This method expects that the connection will start listening for HMR updates and call this callback when it's received. */ onUpdate(callback: (payload: HMRPayload) => void): void } @@ -625,13 +628,13 @@ The callback is queued and it will wait for the current update to be resolved be Plugin hooks also receive the environment name during build. This replaces the `ssr` boolean we have been passing them so far. -The Vite CLI would aslo be updated from `vite build --ssr` to `vite build --environment=ssr`. Applications can then call build for each environment (for example `vite build --environment=workerd`). +The Vite CLI would also be updated from `vite build --ssr` to `vite build --environment=ssr`. Applications can then call build for each environment (for example `vite build --environment=workerd`). -In a future stage, or as part of this proposal, we could also review or stance on vite build being a simple wrapper around rollup. Instead, now that we have a proper environment concept, vite build could create a `ViteBuilder` that has knowledge of all the configured environments and build them all with a single call. This has been requested many times by framework authors that use the "Framework as a plugin" scheme. Right now they end up triggering the SSR build when the `buildEnd` hook for the browser build is called. +In a future stage, or as part of this proposal, we could also review our stance on vite build being a simple wrapper around rollup. Instead, now that we have a proper environment concept, vite build could create a `ViteBuilder` that has knowledge of all the configured environments and build them all with a single call. This has been requested many times by framework authors that use the "Framework as a plugin" scheme. Right now they end up triggering the SSR build when the `buildEnd` hook for the browser build is called. In its simpler form, the vite builder could call each build in series as defined by `config.environments` order (or by a new `config.build.environments` order). This should cover most current use cases out of the box, given that most frameworks build the client first and then SSR (as they use the client manifest). -It is an interesting design space to explore because it could make build and dev work in a more uniform way. For example, Vite Builder could also only load the config file once and do the overrides for each environment in the exact same way as it is done during dev. And there could also be a single plugin pipeline, if we would like plugins to share state directly between the environments (as it happens during dev already). +It is an interesting design space to explore because it could make build and dev work more uniformly. For example, Vite Builder could also only load the config file once and do the overrides for each environment in the same way as it is done during dev. And there could also be a single plugin pipeline if we would like plugins to share state directly between the environments (as it happens during dev already). ## Backward Compatibility @@ -649,22 +652,22 @@ The current Vite server API will be deprecated but keep working during the next The last one is just an idea. We may want to keep `server.open(url)` around. -The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt in until then when releasing the API as experimental in Vite 5.2. +The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt-in until then when releasing the API as experimental in Vite 5.2. ## Open Questions and Alternatives -There are some open questions and alternative as info boxes interlined in the guide. +There are some open questions and alternatives as info boxes interlined in the guide. -Names for concepts and the API are the best we could currently find, what we should keep discussing before releasing if we end up adopting this proposal. Here are some of the alternative naming we discussed in the process of creating this proposal. +Names for concepts and the API are the best we could currently find, which we should keep discussing before releasing if we end up adopting this proposal. Here are some of the alternative names we discussed in the process of creating this proposal. ### ModuleLoader vs Environment -Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. And we could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=ssr` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seems like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. +Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=ssr` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. ### Runtime vs Environment -We also discussed naming runtime to the concept we call environment in this proposal. We decided to go with Environment because a Runtime referes to node, bun, deno, workerd, a browser. But we need to be able to define two different module excecution "environments" for the same runtime. For example SSR and RSC environments, both running in the same node runtime. +We also discussed naming runtime to the concept we call environment in this proposal. We decided to go with Environment because a Runtime refers to node, bun, deno, workerd, a browser. But we need to be able to define two different module execution "environments" for the same runtime. For example SSR and RSC environments, both running in the same node runtime. ### Server and Client -We could also call `ModuleExecutionEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the http server, etc) and client is also used right now to refer to the browser (as in `clientImportedModules`). +We could also call `ModuleExecutionEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the HTTP server, etc), and client is also used right now to refer to the browser (as in `clientImportedModules`). From 058dee37d45be207252d48dea13b17e65356dcf5 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 6 Mar 2024 12:44:53 +0100 Subject: [PATCH 17/41] chore: ssr -> node --- docs/guide/api-vite-environment.md | 58 +++++++++++------------------- docs/images/vite-environments.svg | 14 ++++---- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 6b094670022832..470d43edbdeb56 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -6,7 +6,7 @@ Initial work for this API was introduced in Vite 5.1 with the name [Vite Runtime A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. Some examples of environments are browser, ssr, workerd, rsc. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. -A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime 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 Web Socket and through HTTP requests. The SSR Module runner can directly do function calls to process modules. Other environments could run modules connecting to an edge runtime like workerd, or a Worker Thread in the same node process as Vitest does. +A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime 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 Web Socket 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 an edge runtime like workerd, or a Worker Thread as Vitest does. All these environments share Vite's HTTP server, middlewares, and Web Socket. The resolved config and plugins pipeline are also shared, but plugins can use `apply` so its hooks are only called for certain environments. The environment can also be accessed inside hooks for fine-grained control. @@ -14,7 +14,7 @@ All these environments share Vite's HTTP server, middlewares, and Web Socket. Th ## Using environments in the Vite server -A Vite dev server exposes two environments by default named `'browser'` and `'ssr'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The SSR environment runs in the same runtime as the Vite server (for example, in node) and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. +A Vite dev server exposes two environments by default named `'browser'` and `'node'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The Node environment runs in the same runtime as the Vite server and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. The available environments can be accessed using the `server.environments` read-only array: @@ -34,7 +34,7 @@ An environment is an instance of the `ModuleExecutionEnvironment` class: class ModuleExecutionEnvironment { /** * Unique identifier for the environment in a Vite server. - * By default Vite exposes 'browser' and 'ssr' environments. + * By default Vite exposes 'browser' and 'node' environments. * The ecosystem has consensus on other environments, like 'workerd'. */ name: string @@ -94,7 +94,7 @@ But the environment instance can't execute the code itself, as the runtime where 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. ::: -For the default SSR environment, Vite creates a module runner that implements evaluation using `new AsyncFunction` running in the same runtime as the server. This runner is an instance of `ModuleRunner` that exposes: +For the default Node environment, Vite creates a module runner that implements evaluation using `new AsyncFunction` running in the same runtime as the server. This runner is an instance of `ModuleRunner` that exposes: ```ts class ModuleRunner { @@ -115,7 +115,7 @@ class ModuleRunner { */ ``` -The SSR module runner instance is accessible through `server.ssrModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.ssrModuleRunner` and `server.environment('ssr')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. +The Node module runner instance is accessible through `server.nodeModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.nodeModuleRunner` and `server.environment('node')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. ```js app.use('*', async (req, res, next) => { @@ -132,7 +132,7 @@ app.use('*', async (req, res, next) => { // 3. Load the server entry. executeEntryPoint(url) automatically transforms // ESM source code to be usable in Node.js! There is no bundling // required, and provides full HMR support. - const { render } = await server.ssrModuleRunner.executeEntryPoint( + const { render } = await server.nodeModuleRunner.executeEntryPoint( '/src/entry-server.js', ) @@ -149,22 +149,6 @@ app.use('*', async (req, res, next) => { }) ``` -:::info ssrModuleRunner vs ssrEnvironment - -An alternative is to expose `server.ssrEnvironment` that implements both `ModuleExecutionEnvironment` and `ModuleRunner` as in this case, they are both in the same runtime. In this case, the code above would be: - -```js -const { render } = await server.ssrEnvironment.executeEntryPoint( - '/src/entry-server.js', -) -``` - -This may be an interesting idea if we would like to move other SSR-related methods like `ssrFixStacktrace` from the server to the `ssrEnvironment`. And we could also have `server.browserEnvironment` that extends the environment with browser-specific functionality. - -For this proposal, `server.ssrModuleRunner` is used to highlight the separation between the Environment instance in the server and the module runner instance even if they are both available in the server for SSR. - -::: - ## Plugins and environments The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. @@ -252,10 +236,10 @@ The hook can choose to: In the examples of the previous section, we used a guard in the `hotUpdate` hook to only process updates from the browser environment. If a plugin is specific to only some of the available environments, `apply` can be used to avoid guarding each hook and improve performance. ```js -function ssrOnlyPlugin() { +function nodeOnlyPlugin() { return { - name: 'ssr-only-plugin', - apply({ environment }) => environment === 'ssr', + name: 'node-only-plugin', + apply({ environment }) => environment === 'node', // unguarded hooks... } } @@ -307,8 +291,8 @@ export default { conditions: [] // override for the browser environment } } - ssr: { - optimizeDeps: {} // override for the ssr environment + node: { + optimizeDeps: {} // override for the node environment }, workerd: { noExternal: true // override for a third-party environment @@ -321,7 +305,7 @@ The subset of options that can be overridden are resolved and are available at ` :::info What options can be overridden? -Vite has already allowed defining some config for the [SSR environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overridden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. +Vite has already allowed defining some config for the [Node environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overridden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. We could discuss what other options we should allow to be overridden, although maybe it is better to add them when they are requested by users later on. Some examples: `define`, `resolve.alias`, `resolve.dedupe`, `resolve.mainFields`, `resolve.extensions`. @@ -329,7 +313,7 @@ We could discuss what other options we should allow to be overridden, although m ## Separate module graphs -Vite currently has a mixed browser and ssr module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. +Vite currently has a mixed browser and ssr/node module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. In this proposal, each environment has its module graph (and a backward compatibility layer will be implemented to give time to the ecosystem to migrate). 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. @@ -441,7 +425,7 @@ The environment will be accessible in middlewares or plugin hooks through `serve ## Creating new environments -One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and SSR environments out of the box, but users can build new environments using the exposed primitives. +One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and node environments out of the box, but users can build new environments using the exposed primitives. ```ts import { createModuleExectutionEnvironment } from 'vite' @@ -588,7 +572,7 @@ export interface ModuleEvaluator { } ``` -Vite exports `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](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically in the server SSR environment. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. +Vite exports `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](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically in the server node environment. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. ## HMRModuleRunnerConnection @@ -628,11 +612,11 @@ The callback is queued and it will wait for the current update to be resolved be Plugin hooks also receive the environment name during build. This replaces the `ssr` boolean we have been passing them so far. -The Vite CLI would also be updated from `vite build --ssr` to `vite build --environment=ssr`. Applications can then call build for each environment (for example `vite build --environment=workerd`). +The Vite CLI would also be updated from `vite build --ssr` to `vite build --environment=node`. Applications can then call build for each environment (for example `vite build --environment=workerd`). In a future stage, or as part of this proposal, we could also review our stance on vite build being a simple wrapper around rollup. Instead, now that we have a proper environment concept, vite build could create a `ViteBuilder` that has knowledge of all the configured environments and build them all with a single call. This has been requested many times by framework authors that use the "Framework as a plugin" scheme. Right now they end up triggering the SSR build when the `buildEnd` hook for the browser build is called. -In its simpler form, the vite builder could call each build in series as defined by `config.environments` order (or by a new `config.build.environments` order). This should cover most current use cases out of the box, given that most frameworks build the client first and then SSR (as they use the client manifest). +In its simpler form, the vite builder could call each build in series as defined by `config.environments` order (or by a new `config.build.environments` order). This should cover most current use cases out of the box, given that most frameworks build the client first and then node (as they use the client manifest). It is an interesting design space to explore because it could make build and dev work more uniformly. For example, Vite Builder could also only load the config file once and do the overrides for each environment in the same way as it is done during dev. And there could also be a single plugin pipeline if we would like plugins to share state directly between the environments (as it happens during dev already). @@ -643,16 +627,16 @@ The current Vite server API will be deprecated but keep working during the next | Before | After | | :-------------------------------------------: | :---------------------------------------------------: | | `server.transformRequest(url)` | `server.environment('browser').transformRequest(url)` | -| `server.transformRequest(url, { ssr: true })` | `server.environment('ssr').tranformRequest(url)` | +| `server.transformRequest(url, { ssr: true })` | `server.environment('node').tranformRequest(url)` | | `server.warmupRequest(url)` | `server.environment('browser').warmupRequest(url)` | -| `server.ssrLoadModule(url)` | `server.ssrModuleRunner.executeEntryPoint(url)` | +| `server.ssrLoadModule(url)` | `server.nodeModuleRunner.executeEntryPoint(url)` | | `server.moduleGraph` | `server.environment(name).moduleGraph` | | `handleHotUpdate` | `hotUpdate` | | `server.open(url)` | `server.environment('browser').run(url)` | The last one is just an idea. We may want to keep `server.open(url)` around. -The `server.moduleGraph` will keep returning a mixed view of the browser and ssr module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt-in until then when releasing the API as experimental in Vite 5.2. +The `server.moduleGraph` will keep returning a mixed view of the browser and node module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt-in until then when releasing the API as experimental in Vite 5.2. ## Open Questions and Alternatives @@ -662,7 +646,7 @@ Names for concepts and the API are the best we could currently find, which we sh ### ModuleLoader vs Environment -Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=ssr` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. +Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. ### Runtime vs Environment diff --git a/docs/images/vite-environments.svg b/docs/images/vite-environments.svg index 38ceec80becc99..8f7c133b1d8bc2 100644 --- a/docs/images/vite-environments.svg +++ b/docs/images/vite-environments.svg @@ -7,23 +7,23 @@ src: url("data:font/woff2;base64,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") format("woff2") }Vite Dev ServerVite Dev ServerBrowser  EnvironmentBrowser  -EnvironmentSSR  -EnvironmentSSR  +EnvironmentNode  +EnvironmentNode  EnvironmentBrowser  RuntimeBrowser  RuntimeWorkerd   RuntimeWorkerd   RuntimeWorkerd  EnvironmentWorkerd  -EnvironmentNode-Compatible  -RuntimeNode-Compatible  -RuntimeBrowser  +EnvironmentNode  +RuntimeNode  +RuntimeBrowser  Module  RunnerBrowser  Module  -RunnerSSR  +RunnerNode  Module  -RunnerSSR  +RunnerNode  Module  RunnerWorkerd  Module  From f700f4250a3483d9a141d40dfdb0840caeb04113 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 6 Mar 2024 12:53:30 +0100 Subject: [PATCH 18/41] chore: environment agnostic ssr section --- docs/guide/api-vite-environment.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 470d43edbdeb56..ec5e8ec0536945 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -149,6 +149,22 @@ app.use('*', async (req, res, next) => { }) ``` +## Environment agnostic SSR + +One of the objectives of this proposal is to allow users to swap Vite's default SSR environment. Out-of-the-box, Vite will use a node environment running on the same process as the server. But a user may want to swap it for a workerd environment. + +Vite would expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.nodeModuleRunner`, the example above would be written as: + +```js +// 3. Load the server entry, with full HMR support. +const { render } = await server.ssrEnvironment.run('/src/entry-server.js') + +// 4. render the app HTML. +const appHtml = await render(url) +``` + +`run(url)` would return RPC wrappers for `entry-server` exported functions, so that this code is compatible with both node and workerd environments. + ## Plugins and environments The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. From f0f62c76afc965690a6ca2147ab43f5767b2e190 Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Wed, 6 Mar 2024 22:54:48 +0100 Subject: [PATCH 19/41] chore: typo Co-authored-by: Igor Minar --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index ec5e8ec0536945..7f246d04c0b336 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -1,7 +1,7 @@ # Vite Environment API :::warning Low-level API -Initial work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environemnt API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +Initial work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. ::: A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. Some examples of environments are browser, ssr, workerd, rsc. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. From cea32889d4a62c36223c1f8c777cbdce7a36f248 Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:51:43 +0100 Subject: [PATCH 20/41] chore: typo Co-authored-by: Igor Minar --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 7f246d04c0b336..0aaf9f9b028688 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -255,7 +255,7 @@ In the examples of the previous section, we used a guard in the `hotUpdate` hook function nodeOnlyPlugin() { return { name: 'node-only-plugin', - apply({ environment }) => environment === 'node', + apply: ({ environment }) => environment === 'node', // unguarded hooks... } } From 0a06fd3357d0223f5d20b6723da2295eff65844e Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:52:10 +0100 Subject: [PATCH 21/41] chore: update Co-authored-by: Igor Minar --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 0aaf9f9b028688..b6a7623bc027d8 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -427,7 +427,7 @@ There is a new plugin hook called `registerEnvironment` that is called after `co function workedPlugin() { return { name: 'vite-plugin-workerd', - registerEnvironment(server, environments) { + registerEnvironment: (server, environments) => { const workedEnvironment = new WorkerdEnvironment(server) // This environment has 'workerd' as its name, a convention agreed upon by the ecosystem // connect workerdEnviroment logic to its associated workerd module runner From 8c537987182a34a13abc5b07fe944d5e3561ea2a Mon Sep 17 00:00:00 2001 From: patak Date: Thu, 7 Mar 2024 06:58:06 +0100 Subject: [PATCH 22/41] chore: add TransformResult type --- docs/guide/api-vite-environment.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index b6a7623bc027d8..0ff47c683aa3e1 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -69,7 +69,7 @@ class ModuleExecutionEnvironment { * Resolve the URL to an id, load it, and process the code using the * plugins pipeline. The module graph is also updated. */ - async transformRequest(url: string) + async transformRequest(url: string): TransformResult /** * Register a request to be processed with low priority. This is useful @@ -77,7 +77,7 @@ class ModuleExecutionEnvironment { * modules by other requests, so it can warmup the module graph so the * modules are already processed when they are requested. */ - async warmupRequest(url: string) + async warmupRequest(url: string): void /** * Fetch information about a module from the module runner without running it. @@ -86,6 +86,18 @@ class ModuleExecutionEnvironment { } ``` +With `TransformResult` being: + +```ts +interface TransformResult { + code: string + map: SourceMap | { mappings: '' } | null + etag?: string + deps?: string[] + dynamicDeps?: string[] +} +``` + 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. But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.environment('browser').transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. From 650106656b0aa8dcb45fc8a277a5b5c796f5dcf4 Mon Sep 17 00:00:00 2001 From: patak Date: Fri, 8 Mar 2024 08:12:13 +0100 Subject: [PATCH 23/41] chore: clarify run --- docs/guide/api-vite-environment.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 0ff47c683aa3e1..6aef84cb41bfd0 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -81,8 +81,9 @@ class ModuleExecutionEnvironment { /** * Fetch information about a module from the module runner without running it. + * Note: This method may not be needed */ - async fetch(url: string) + async fetchModuleInfo(url: string) } ``` @@ -127,6 +128,10 @@ class ModuleRunner { */ ``` +:::info +We are using `executeUrl` and `executeEntryPoint` to keep the API familiar with the current Runtime API. This two methods could end up merged as single one and renamed. For example `runner.import(url, { hmr: false })` or `runner.load(url)`. +::: + The Node module runner instance is accessible through `server.nodeModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.nodeModuleRunner` and `server.environment('node')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. ```js @@ -165,17 +170,22 @@ app.use('*', async (req, res, next) => { One of the objectives of this proposal is to allow users to swap Vite's default SSR environment. Out-of-the-box, Vite will use a node environment running on the same process as the server. But a user may want to swap it for a workerd environment. -Vite would expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.nodeModuleRunner`, the example above would be written as: +Vite could expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.nodeModuleRunner`, the example above would be written as: ```js // 3. Load the server entry, with full HMR support. -const { render } = await server.ssrEnvironment.run('/src/entry-server.js') +// Only functions that accepts serializable params and results are supported. +const { render } = await server.ssrEnvironment.import('/src/entry-server.js') // 4. render the app HTML. const appHtml = await render(url) ``` -`run(url)` would return RPC wrappers for `entry-server` exported functions, so that this code is compatible with both node and workerd environments. +`import(url)` would return RPC wrappers for `entry-server` exported functions, so that this code is compatible with both node and workerd environments. + +A `environment.import(url): RPC exports` may be difficult to implement across all environments. So it isn't part of the initial proposal. Given that a lot of projects in the ecosystem end up re-implementating a RPC scheme, we could add it later as a feature that can be supported by a subset of all environments and promote its use only for use cases that don't target universal runtime support. For example, for tools using Vite that are intended to run in a node like environment and want to use a worker thread environment like Vitest. + +In this proposal, environments expose a `environment.run(url): void` function to request running the url in the associated module runner. ## Plugins and environments @@ -460,14 +470,13 @@ import { createModuleExectutionEnvironment } from 'vite' const environment = createModuleExecutionEnvironment({ name: 'workerd', - hot: null, config: { resolve: { conditions: ['custom'] } }, run(url) { - return rpc().runModule(url) + dispatchModuleRunInWorkerd(url) } -}) => ViteModuleExecutionEnvironment +}) => ModuleExecutionEnvironment ``` ## `ModuleRunner` From 9086fc59ab619850eb9d17caafe34da2a6475c60 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 12 Mar 2024 12:54:05 +0100 Subject: [PATCH 24/41] docs: move vite runtime API to vite environment section (#16149) --- docs/blog/announcing-vite5-1.md | 2 - docs/guide/api-vite-environment.md | 53 +++---- docs/guide/api-vite-runtime.md | 234 ----------------------------- 3 files changed, 20 insertions(+), 269 deletions(-) delete mode 100644 docs/guide/api-vite-runtime.md diff --git a/docs/blog/announcing-vite5-1.md b/docs/blog/announcing-vite5-1.md index b5f7c72a8dd6c7..bb0fb3d7ce80e2 100644 --- a/docs/blog/announcing-vite5-1.md +++ b/docs/blog/announcing-vite5-1.md @@ -56,8 +56,6 @@ The new API brings many benefits: The initial idea [was proposed by Pooya Parsa](https://github.com/nuxt/vite/pull/201) and implemented by [Anthony Fu](https://github.com/antfu) as the [vite-node](https://github.com/vitest-dev/vitest/tree/main/packages/vite-node#readme) package to [power Nuxt 3 Dev SSR](https://antfu.me/posts/dev-ssr-on-nuxt) and later also used as the base for [Vitest](https://vitest.dev). So the general idea of vite-node has been battle-tested for quite some time now. This is a new iteration of the API by [Vladimir Sheremet](https://github.com/sheremet-va), who had already re-implemented vite-node in Vitest and took the learnings to make the API even more powerful and flexible when adding it to Vite Core. The PR was one year in the makings, you can see the evolution and discussions with ecosystem maintainers [here](https://github.com/vitejs/vite/issues/12165). -Read more in the [Vite Runtime API guide](/guide/api-vite-runtime) and [give us feedback](https://github.com/vitejs/vite/discussions/15774). - ## Features ### Improved support for `.css?url` diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 6aef84cb41bfd0..e20bb67124e798 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -1,12 +1,12 @@ # Vite Environment API :::warning Low-level API -Initial work for this API was introduced in Vite 5.1 with the name [Vite Runtime API](./api-vite-runtime.md). In Vite 5.2 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". In Vite 5.2 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. ::: A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. Some examples of environments are browser, ssr, workerd, rsc. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. -A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime 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 Web Socket 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 an edge runtime like workerd, or a Worker Thread as Vitest does. +A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.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 Web Socket 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 an edge runtime like workerd, or a Worker Thread as Vitest does. All these environments share Vite's HTTP server, middlewares, and Web Socket. The resolved config and plugins pipeline are also shared, but plugins can use `apply` so its hooks are only called for certain environments. The environment can also be accessed inside hooks for fine-grained control. @@ -115,21 +115,14 @@ class ModuleRunner { * URL to execute. Accepts file path, server path, or id relative to the root. * Returns an instantiated module (same as in ssrLoadModule) */ - public async executeUrl(url: string): Promise> - /** - * Entry point URL to execute. Accepts file path, server path or id relative to the root. - * In the case of a full reload triggered by HMR, this is the module that will be reloaded. - * If this method is called multiple times, all entry points will be reloaded one at a time. - * Returns an instantiated module - */ - public async executeEntrypoint(url: string): Promise> + public async import(url: string): Promise> /** * Other ModuleRunner methods... */ ``` :::info -We are using `executeUrl` and `executeEntryPoint` to keep the API familiar with the current Runtime API. This two methods could end up merged as single one and renamed. For example `runner.import(url, { hmr: false })` or `runner.load(url)`. +In the previous iteration, we had `executeUrl` and `executeEntryPoint` methods - they are now merged into a single `import` method. If you want to opt-out of the HMR support, create a runner with `hmr: false` flag. ::: The Node module runner instance is accessible through `server.nodeModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.nodeModuleRunner` and `server.environment('node')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. @@ -146,10 +139,10 @@ app.use('*', async (req, res, next) => { // preambles from @vitejs/plugin-react template = await server.transformIndexHtml(url, template) - // 3. Load the server entry. executeEntryPoint(url) automatically transforms + // 3. Load the server entry. import(url) automatically transforms // ESM source code to be usable in Node.js! There is no bundling // required, and provides full HMR support. - const { render } = await server.nodeModuleRunner.executeEntryPoint( + const { render } = await server.nodeModuleRunner.import( '/src/entry-server.js', ) @@ -495,13 +488,7 @@ export class ModuleRunner { /** * URL to execute. Accepts file path, server path, or id relative to the root. */ - public async executeUrl(url: string): Promise - /** - * Entry point URL to execute. Accepts file path, server path or id relative to the root. - * In the case of a full reload triggered by HMR, this is the module that will be reloaded. - * If this method is called multiple times, all entry points will be reloaded one at a time. - */ - public async executeEntrypoint(url: string): Promise + public async import(url: string): Promise /** * Clear all caches including HMR listeners. */ @@ -512,7 +499,7 @@ export class ModuleRunner { */ public async destroy(): Promise /** - * Returns `true` if the runtime has been destroyed by calling `destroy()` method. + * Returns `true` if the runner has been destroyed by calling `destroy()` method. */ public isDestroyed(): boolean } @@ -520,12 +507,12 @@ export class ModuleRunner { The module evaluator in `ModuleRunner` is responsible for executing the code. Vite exports `ESModulesEvaluator` out of the box, it uses `new AsyncFunction` to evaluate the code. You can provide your own implementation if your JavaScript runtime doesn't support unsafe evaluation. -The two main methods that a module runner exposes are `executeUrl` and `executeEntrypoint`. The only difference between them is that all modules executed by `executeEntrypoint` will be re-executed if HMR triggers `full-reload` event. Be aware that Vite module runners don't update the `exports` object when this happens, instead, it overrides it. You would need to run `executeUrl` or get the module from the `moduleCache` again if you rely on having the latest `exports` object. +Module runner exposes `import` method. 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 `moduleCache` again if you rely on having the latest `exports` object. **Example Usage:** ```js -import { ModuleRunner, ESModulesEvaluator } from 'vite/environment' +import { ModuleRunner, ESModulesEvaluator } from 'vite/module-runner' import { root, fetchModule } from './rpc-implementation.js' const moduleRunner = new ModuleRunner( @@ -537,7 +524,7 @@ const moduleRunner = new ModuleRunner( new ESModulesEvaluator(), ) -await moduleRunner.executeEntrypoint('/src/entry-point.js') +await moduleRunner.import('/src/entry-point.js') ``` ## `ModuleRunnerOptions` @@ -571,14 +558,14 @@ export interface ModuleRunnerOptions { /** * Configure how HMR communicates between the client and the server. */ - connection: HMRRuntimeConnection + connection: ModuleRunnerHMRConnection /** * Configure HMR logger. */ logger?: false | HMRLogger } /** - * Custom module cache. If not provided, it creates a separate module cache for each ViteRuntime instance. + * Custom module cache. If not provided, it creates a separate module cache for each module runner instance. */ moduleCache?: ModuleCacheMap } @@ -596,7 +583,7 @@ export interface ModuleEvaluator { * @param code Transformed code * @param id ID that was used to fetch the module */ - evaluateModule( + runInlinedModule( context: ModuleRunnerContext, code: string, id: string, @@ -605,18 +592,18 @@ export interface ModuleEvaluator { * evaluate externalized module. * @param file File URL to the external module */ - evaluateExternalModule(file: string): Promise + runExternalModule(file: string): Promise } ``` Vite exports `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](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically in the server node environment. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. -## HMRModuleRunnerConnection +## ModuleRunnerHMRConnection **Type Signature:** ```ts -export interface HMRModuleRunnerConnection { +export interface ModuleRunnerHMRConnection { /** * Checked before sending messages to the client. */ @@ -635,7 +622,7 @@ export interface HMRModuleRunnerConnection { This interface defines how HMR communication is established. Vite exports `ServerHMRConnector` from the main entry point to support HMR during Vite SSR. The `isReady` and `send` methods are usually called when the custom event is triggered (like, `import.meta.hot.send("my-event")`). -`onUpdate` is called only once when the new runtime is initiated. It passed down a method that should be called when connection triggers the HMR event. The implementation depends on the type of connection (as an example, it can be `WebSocket`/`EventEmitter`/`MessageChannel`), but it usually looks something like this: +`onUpdate` is called only once when the new module runner is initiated. It passed down a method that should be called when connection triggers the HMR event. The implementation depends on the type of connection (as an example, it can be `WebSocket`/`EventEmitter`/`MessageChannel`), but it usually looks something like this: ```js function onUpdate(callback) { @@ -643,7 +630,7 @@ function onUpdate(callback) { } ``` -The callback is queued and it will wait for the current update to be resolved before processing the next update. Unlike the browser implementation, HMR updates in Vite Runtime wait until all listeners (like, `vite:beforeUpdate`/`vite:beforeFullReload`) are finished before updating the modules. +The callback is queued and it will wait for the current update to be resolved before processing the next update. Unlike the browser implementation, HMR updates in a module runner will wait until all listeners (like, `vite:beforeUpdate`/`vite:beforeFullReload`) are finished before updating the modules. ## Environments during build @@ -666,7 +653,7 @@ The current Vite server API will be deprecated but keep working during the next | `server.transformRequest(url)` | `server.environment('browser').transformRequest(url)` | | `server.transformRequest(url, { ssr: true })` | `server.environment('node').tranformRequest(url)` | | `server.warmupRequest(url)` | `server.environment('browser').warmupRequest(url)` | -| `server.ssrLoadModule(url)` | `server.nodeModuleRunner.executeEntryPoint(url)` | +| `server.ssrLoadModule(url)` | `server.nodeModuleRunner.import(url)` | | `server.moduleGraph` | `server.environment(name).moduleGraph` | | `handleHotUpdate` | `hotUpdate` | | `server.open(url)` | `server.environment('browser').run(url)` | diff --git a/docs/guide/api-vite-runtime.md b/docs/guide/api-vite-runtime.md deleted file mode 100644 index 5c4ee3f07c3ec5..00000000000000 --- a/docs/guide/api-vite-runtime.md +++ /dev/null @@ -1,234 +0,0 @@ -# Vite Runtime API - -:::warning Low-level API -This API was introduced in Vite 5.1 as an experimental feature. It was added to [gather feedback](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.2, so make sure to pin the Vite version to `~5.1.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. -::: - -The "Vite Runtime" is a tool that allows running any code by processing it with Vite plugins first. It is different from `server.ssrLoadModule` because the runtime implementation is decoupled from the server. This allows library and framework authors to implement their own layer of communication between the server and the runtime. - -One of the goals of this feature is to provide a customizable API to process and run the code. Vite provides enough tools to use Vite Runtime out of the box, but users can build upon it if their needs do not align with Vite's built-in implementation. - -All APIs can be imported from `vite/runtime` unless stated otherwise. - -## `ViteRuntime` - -**Type Signature:** - -```ts -export class ViteRuntime { - constructor( - public options: ViteRuntimeOptions, - public runner: ViteModuleRunner, - private debug?: ViteRuntimeDebugger, - ) {} - /** - * URL to execute. Accepts file path, server path, or id relative to the root. - */ - public async executeUrl(url: string): Promise - /** - * Entry point URL to execute. Accepts file path, server path or id relative to the root. - * In the case of a full reload triggered by HMR, this is the module that will be reloaded. - * If this method is called multiple times, all entry points will be reloaded one at a time. - */ - public async executeEntrypoint(url: string): Promise - /** - * Clear all caches including HMR listeners. - */ - public clearCache(): void - /** - * Clears all caches, removes all HMR listeners, and resets source map support. - * This method doesn't stop the HMR connection. - */ - public async destroy(): Promise - /** - * Returns `true` if the runtime has been destroyed by calling `destroy()` method. - */ - public isDestroyed(): boolean -} -``` - -::: tip Advanced Usage -If you are just migrating from `server.ssrLoadModule` and want to support HMR, consider using [`createViteRuntime`](#createviteruntime) instead. -::: - -The `ViteRuntime` class requires `root` and `fetchModule` options when initiated. Vite exposes `ssrFetchModule` on the [`server`](/guide/api-javascript) instance for easier integration with Vite SSR. Vite also exports `fetchModule` from its main entry point - it doesn't make any assumptions about how the code is running unlike `ssrFetchModule` that expects the code to run using `new Function`. This can be seen in source maps that these functions return. - -Runner in `ViteRuntime` is responsible for executing the code. Vite exports `ESModulesRunner` out of the box, it uses `new AsyncFunction` to run the code. You can provide your own implementation if your JavaScript runtime doesn't support unsafe evaluation. - -The two main methods that runtime exposes are `executeUrl` and `executeEntrypoint`. The only difference between them is that all modules executed by `executeEntrypoint` will be reexecuted if HMR triggers `full-reload` event. Be aware that Vite Runtime doesn't update `exports` object when this happens (it overrides it), you would need to run `executeUrl` or get the module from `moduleCache` again if you rely on having the latest `exports` object. - -**Example Usage:** - -```js -import { ViteRuntime, ESModulesRunner } from 'vite/runtime' -import { root, fetchModule } from './rpc-implementation.js' - -const runtime = new ViteRuntime( - { - root, - fetchModule, - // you can also provide hmr.connection to support HMR - }, - new ESModulesRunner(), -) - -await runtime.executeEntrypoint('/src/entry-point.js') -``` - -## `ViteRuntimeOptions` - -```ts -export interface ViteRuntimeOptions { - /** - * Root of the project - */ - root: string - /** - * A method to get the information about the module. - * For SSR, Vite exposes `server.ssrFetchModule` function that you can use here. - * For other runtime use cases, Vite also exposes `fetchModule` from its main entry point. - */ - fetchModule: FetchFunction - /** - * 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. - */ - sourcemapInterceptor?: - | false - | 'node' - | 'prepareStackTrace' - | InterceptorOptions - /** - * Disable HMR or configure HMR options. - */ - hmr?: - | false - | { - /** - * Configure how HMR communicates between the client and the server. - */ - connection: HMRRuntimeConnection - /** - * Configure HMR logger. - */ - logger?: false | HMRLogger - } - /** - * Custom module cache. If not provided, it creates a separate module cache for each ViteRuntime instance. - */ - moduleCache?: ModuleCacheMap -} -``` - -## `ViteModuleRunner` - -**Type Signature:** - -```ts -export interface ViteModuleRunner { - /** - * Run code that was transformed by Vite. - * @param context Function context - * @param code Transformed code - * @param id ID that was used to fetch the module - */ - runViteModule( - context: ViteRuntimeModuleContext, - code: string, - id: string, - ): Promise - /** - * Run externalized module. - * @param file File URL to the external module - */ - runExternalModule(file: string): Promise -} -``` - -Vite exports `ESModulesRunner` that implements this interface by default. It uses `new AsyncFunction` to run code, so if the code has inlined source map it should contain an [offset of 2 lines](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically by `server.ssrFetchModule`. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. - -## HMRRuntimeConnection - -**Type Signature:** - -```ts -export interface HMRRuntimeConnection { - /** - * Checked before sending messages to the client. - */ - isReady(): boolean - /** - * Send message to the client. - */ - send(message: string): void - /** - * Configure how HMR is handled when this connection triggers an update. - * This method expects that connection will start listening for HMR updates and call this callback when it's received. - */ - onUpdate(callback: (payload: HMRPayload) => void): void -} -``` - -This interface defines how HMR communication is established. Vite exports `ServerHMRConnector` from the main entry point to support HMR during Vite SSR. The `isReady` and `send` methods are usually called when the custom event is triggered (like, `import.meta.hot.send("my-event")`). - -`onUpdate` is called only once when the new runtime is initiated. It passed down a method that should be called when connection triggers the HMR event. The implementation depends on the type of connection (as an example, it can be `WebSocket`/`EventEmitter`/`MessageChannel`), but it usually looks something like this: - -```js -function onUpdate(callback) { - this.connection.on('hmr', (event) => callback(event.data)) -} -``` - -The callback is queued and it will wait for the current update to be resolved before processing the next update. Unlike the browser implementation, HMR updates in Vite Runtime wait until all listeners (like, `vite:beforeUpdate`/`vite:beforeFullReload`) are finished before updating the modules. - -## `createViteRuntime` - -**Type Signature:** - -```ts -async function createViteRuntime( - server: ViteDevServer, - options?: MainThreadRuntimeOptions, -): Promise -``` - -**Example Usage:** - -```js -import { createServer } from 'vite' - -const __dirname = fileURLToPath(new URL('.', import.meta.url)) - -;(async () => { - const server = await createServer({ - root: __dirname, - }) - await server.listen() - - const runtime = await createViteRuntime(server) - await runtime.executeEntrypoint('/src/entry-point.js') -})() -``` - -This method serves as an easy replacement for `server.ssrLoadModule`. Unlike `ssrLoadModule`, `createViteRuntime` provides HMR support out of the box. You can pass down [`options`](#mainthreadruntimeoptions) to customize how SSR runtime behaves to suit your needs. - -## `MainThreadRuntimeOptions` - -```ts -export interface MainThreadRuntimeOptions - extends Omit { - /** - * Disable HMR or configure HMR logger. - */ - hmr?: - | false - | { - logger?: false | HMRLogger - } - /** - * Provide a custom module runner. This controls how the code is executed. - */ - runner?: ViteModuleRunner -} -``` From 5bc14bc4d4eb4a42f3fbefe03fb0ec5dce9a13f2 Mon Sep 17 00:00:00 2001 From: patak Date: Fri, 15 Mar 2024 22:06:49 +0100 Subject: [PATCH 25/41] chore: rename ModuleExecutionEnvironment to DevEnvironment --- docs/guide/api-vite-environment.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index e20bb67124e798..ce377c48fe5726 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -28,14 +28,13 @@ Each environment can also be accessed through its name: server.environment('browser').transformRequest(url) ``` -An environment is an instance of the `ModuleExecutionEnvironment` class: +An environment is an instance of the `DevEnvironment` class: ```ts -class ModuleExecutionEnvironment { +class DevEnvironment { /** * Unique identifier for the environment in a Vite server. * By default Vite exposes 'browser' and 'node' environments. - * The ecosystem has consensus on other environments, like 'workerd'. */ name: string /** @@ -60,10 +59,7 @@ class ModuleExecutionEnvironment { */ config: ResolvedEnvironmentConfig - constructor( - server, - { name, hot, run, config }: ModuleExecutionEnvironmentOptions, - ) + constructor(server, { name, hot, run, config }: DevEnvironmentOptions) /** * Resolve the URL to an id, load it, and process the code using the @@ -461,7 +457,7 @@ One of the goals of this feature is to provide a customizable API to process and ```ts import { createModuleExectutionEnvironment } from 'vite' -const environment = createModuleExecutionEnvironment({ +const environment = createDevEnvironment({ name: 'workerd', config: { resolve: { conditions: ['custom'] } @@ -469,7 +465,7 @@ const environment = createModuleExecutionEnvironment({ run(url) { dispatchModuleRunInWorkerd(url) } -}) => ModuleExecutionEnvironment +}) => DevEnvironment ``` ## `ModuleRunner` @@ -670,7 +666,7 @@ Names for concepts and the API are the best we could currently find, which we sh ### ModuleLoader vs Environment -Instead of `ModuleExecutionEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. +Instead of `DevEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. ### Runtime vs Environment @@ -678,4 +674,4 @@ We also discussed naming runtime to the concept we call environment in this prop ### Server and Client -We could also call `ModuleExecutionEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the HTTP server, etc), and client is also used right now to refer to the browser (as in `clientImportedModules`). +We could also call `DevEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the HTTP server, etc), and client is also used right now to refer to the browser (as in `clientImportedModules`). From 2c8430f88f243d465ab1d1b272074cefc2b558af Mon Sep 17 00:00:00 2001 From: patak Date: Sun, 17 Mar 2024 06:47:41 +0100 Subject: [PATCH 26/41] feat: environments configuration --- docs/guide/api-vite-environment.md | 221 ++++++++++++++++++++--------- 1 file changed, 154 insertions(+), 67 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index ce377c48fe5726..13ddcdf7d08d66 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -16,19 +16,15 @@ All these environments share Vite's HTTP server, middlewares, and Web Socket. Th A Vite dev server exposes two environments by default named `'browser'` and `'node'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The Node environment runs in the same runtime as the Vite server and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. -The available environments can be accessed using the `server.environments` read-only array: +The available environments can be accessed using the `server.environments` map: ```js server.environments.forEach((environment) => log(environment.name)) -``` - -Each environment can also be accessed through its name: -```js -server.environment('browser').transformRequest(url) +server.environments.get('browser').transformRequest(url) ``` -An environment is an instance of the `DevEnvironment` class: +An dev environment is an instance of the `DevEnvironment` class: ```ts class DevEnvironment { @@ -48,6 +44,7 @@ class DevEnvironment { */ moduleGraph: ModuleGraph /** + * TBD: This abstraction isn't yet clear * Trigger the execution of a module using the associated module runner * in the target runtime. */ @@ -303,41 +300,6 @@ We could also make the environment name or common environment object accessible ::: -## Environment Configuration - -All environments share the Vite server configuration, but certain options can be overridden per environment. - -```js -export default { - resolve: { - conditions: [] // shared by all environments - }, - environment: { - browser: { - resolve: { - conditions: [] // override for the browser environment - } - } - node: { - optimizeDeps: {} // override for the node environment - }, - workerd: { - noExternal: true // override for a third-party environment - } - } -} -``` - -The subset of options that can be overridden are resolved and are available at `environment.config`. - -:::info What options can be overridden? - -Vite has already allowed defining some config for the [Node environment](https://vitejs.dev/config/ssr-options.html). Initially, these are the options that would be available to be overridden by any environment. Except for `ssr.target: 'node' | 'webworker'`, that could be deprecated as `webworker` could be implemented as a separate environment. - -We could discuss what other options we should allow to be overridden, although maybe it is better to add them when they are requested by users later on. Some examples: `define`, `resolve.alias`, `resolve.dedupe`, `resolve.mainFields`, `resolve.extensions`. - -::: - ## Separate module graphs Vite currently has a mixed browser and ssr/node module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. @@ -430,44 +392,133 @@ export class ModuleGraph { } ``` -## Registering environments - -There is a new plugin hook called `registerEnvironment` that is called after `configResolved`: - -```js -function workedPlugin() { - return { - name: 'vite-plugin-workerd', - registerEnvironment: (server, environments) => { - const workedEnvironment = new WorkerdEnvironment(server) - // This environment has 'workerd' as its name, a convention agreed upon by the ecosystem - // connect workerdEnviroment logic to its associated workerd module runner - environments.push(workedEnvironment) - }, - } -} -``` - -The environment will be accessible in middlewares or plugin hooks through `server.environment('workerd')`. - ## Creating new environments One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and node environments out of the box, but users can build new environments using the exposed primitives. ```ts -import { createModuleExectutionEnvironment } from 'vite' +import { createDevEnvironment } from 'vite' -const environment = createDevEnvironment({ +const environment = new DevEnvironment({ name: 'workerd', config: { resolve: { conditions: ['custom'] } }, + // TBD run(url) { dispatchModuleRunInWorkerd(url) } }) => DevEnvironment ``` +## Environment Configuration + +All environments share the Vite server configuration, but certain options can be overriden per environment. + +```js +export default { + resolve: { + conditions: [] // shared by all environments + }, + environments: { + browser: { + resolve: { + conditions: [] // override for the browser environment + } + } + node: { + optimizeDeps: {} // override for the node environment + }, + workerd: { + noExternal: true // override for a third-party environment + } + } +} +``` + +The `EnvironmentConfig` interface exposes all the per-environment options. There are `SharedEnvironmentConfig` that apply to both `build` and `dev` environments, like `resolve`. And there are `DevOptions` and `BuildOptions` + +```ts +interface EnvironmentConfig extends SharedEnvironmentConfig { + dev: DevOptions + build: BuildOptions +} +``` + +The `UserConfig` interface extends from `EnvironmentConfig`. Environment specific options defined at the root level of user config are used as the default for all environments. A user can use the `environments` record to override default options for any environment. + +```ts +interface UserConfig extends EnvironmentConfig { + environments: { + [id]: EnvironmentConfig + } + // other options +} +``` + +## Registering environments + +To register a new dev or build environment, you can use a `create` function: + +```js +export default { + environments: { + rsc: { + dev: { + create: (server) => new NodeDevEnvironment(server), + }, + build: { + create: (builder) => new NodeBuildEnvironment(builder), + outDir: '/dist/rsc', + }, + }, + }, +} +``` + +Environment providers like Workerd, can expose an environment configurator for the most common case of using the same runtime for both dev and build environments. The default environment options can also be set so the user doesn't need to do it. + +```js +function workedEnvironment(userConfig) { + return mergeConfig( + { + resolve: { + conditions: [ + /*...*/ + ], + }, + dev: { + createEnvironment: (server, name) => + new WorkerdDevEnvironment(server, name), + }, + build: { + createEnvironment: (builder, name) => + new WorkerdBuildEnvironment(builder, name), + }, + }, + userConfig, + ) +} +``` + +Then the config file can be writen as + +```js +import { workerdEnvironment } from 'vite-environment-workerd' + +export default { + environments: { + rsc: workerdEnvironment({ + build: { + outDir: '/dist/rsc', + }, + }), + }, +} +``` + +The environment will be accessible in middlewares or plugin hooks through `server.environment('workerd')`. + ## `ModuleRunner` A module runner is instantiated in the target runtime. All APIs in the next section are imported from `vite/module-runner` unless stated otherwise. This export entry point is kept as lightweight as possible, only exporting the minimal needed to create runners in the @@ -634,11 +685,47 @@ Plugin hooks also receive the environment name during build. This replaces the ` The Vite CLI would also be updated from `vite build --ssr` to `vite build --environment=node`. Applications can then call build for each environment (for example `vite build --environment=workerd`). -In a future stage, or as part of this proposal, we could also review our stance on vite build being a simple wrapper around rollup. Instead, now that we have a proper environment concept, vite build could create a `ViteBuilder` that has knowledge of all the configured environments and build them all with a single call. This has been requested many times by framework authors that use the "Framework as a plugin" scheme. Right now they end up triggering the SSR build when the `buildEnd` hook for the browser build is called. +Calling `vite build --all` will instantiate a `ViteBuilder` (equivalent to a `ViteDevServer`) and build all configured environments. By default the build of environment is runned in series, but a framework or user can configure it using: -In its simpler form, the vite builder could call each build in series as defined by `config.environments` order (or by a new `config.build.environments` order). This should cover most current use cases out of the box, given that most frameworks build the client first and then node (as they use the client manifest). +```js +export default { + builder: { + runBuildTasks: asnyc (builder, buildTasks) => { + return Promise.all(buildTasks.map( task => task.run() )) + } + } +} +``` + +A build task implements the `BuildTask` interface: + +```js +export interface BuildTask { + environment: BuildEnvironment + config: ResolvedConfig + run: () => Promise + cancel: () => void +} +``` + +::: info + +If we have a requirement to create environments dynamically, for example to create an environment depending on the folder structure of user projects at startup. We could let frameworks provide a function at the `server` and `builder` level to do so. -It is an interesting design space to explore because it could make build and dev work more uniformly. For example, Vite Builder could also only load the config file once and do the overrides for each environment in the same way as it is done during dev. And there could also be a single plugin pipeline if we would like plugins to share state directly between the environments (as it happens during dev already). +```js +builder: { + configureEnvironments: async (builder, environments) => { + // Dynamically add build environments + } +}, +server: { + configureEnvironments: (server, environments) => { + // Dynamically add dev environments + } +} +``` + +::: ## Backward Compatibility From 676e1dc14f2c79577bc5e4ae1376f3e8937406c0 Mon Sep 17 00:00:00 2001 From: patak Date: Tue, 19 Mar 2024 18:28:17 +0100 Subject: [PATCH 27/41] docs: environments from map to array --- docs/guide/api-vite-environment.md | 49 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 13ddcdf7d08d66..3ab7f0508c8bdb 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -16,12 +16,10 @@ All these environments share Vite's HTTP server, middlewares, and Web Socket. Th A Vite dev server exposes two environments by default named `'browser'` and `'node'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The Node environment runs in the same runtime as the Vite server and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. -The available environments can be accessed using the `server.environments` map: +The available environments can be accessed using the `server.environments` array: ```js server.environments.forEach((environment) => log(environment.name)) - -server.environments.get('browser').transformRequest(url) ``` An dev environment is an instance of the `DevEnvironment` class: @@ -418,21 +416,24 @@ All environments share the Vite server configuration, but certain options can be ```js export default { resolve: { - conditions: [] // shared by all environments + conditions: [], // shared by all environments }, - environments: { - browser: { + environments: [ + { + name: 'browser', resolve: { - conditions: [] // override for the browser environment - } - } - node: { - optimizeDeps: {} // override for the node environment + conditions: [], // override for the browser environment + }, }, - workerd: { - noExternal: true // override for a third-party environment - } - } + { + name: 'node', + optimizeDeps: {}, // override for the node environment + }, + { + name: 'workerd', + noExternal: true, // override for a third-party environment + }, + ], } ``` @@ -449,9 +450,7 @@ The `UserConfig` interface extends from `EnvironmentConfig`. Environment specifi ```ts interface UserConfig extends EnvironmentConfig { - environments: { - [id]: EnvironmentConfig - } + environments: (EnvironmentConfig & { name: string })[] // other options } ``` @@ -462,8 +461,9 @@ To register a new dev or build environment, you can use a `create` function: ```js export default { - environments: { - rsc: { + environments: [ + { + name: 'rsc', dev: { create: (server) => new NodeDevEnvironment(server), }, @@ -472,7 +472,7 @@ export default { outDir: '/dist/rsc', }, }, - }, + ], } ``` @@ -507,13 +507,14 @@ Then the config file can be writen as import { workerdEnvironment } from 'vite-environment-workerd' export default { - environments: { - rsc: workerdEnvironment({ + environments: [ + workerdEnvironment({ + name: 'rsc', build: { outDir: '/dist/rsc', }, }), - }, + ], } ``` From 17190bdcba21190c637cf9a6721ca05418a05cad Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:55:32 +0100 Subject: [PATCH 28/41] docs: environment api client/ssr revision (#16202) --- docs/guide/api-vite-environment.md | 177 +++++++++++++---------------- 1 file changed, 79 insertions(+), 98 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 3ab7f0508c8bdb..b3835007b28aa5 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -4,7 +4,7 @@ Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". In Vite 5.2 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. ::: -A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. Some examples of environments are browser, ssr, workerd, rsc. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. +A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. In a typical Vite app, an environments will be used for the ES modules served to the client and for the server program that does SSR. An app can do SSR on a Node server, but also on an edge runtime like Workerd. So we can have different types of environments on the same Vite server: browser environments, node environments, and workerd environments to name a few. A Vite Module Runner allows running any code by processing it with Vite plugins first. It is different from `server.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 Web Socket 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 an edge runtime like workerd, or a Worker Thread as Vitest does. @@ -14,7 +14,7 @@ All these environments share Vite's HTTP server, middlewares, and Web Socket. Th ## Using environments in the Vite server -A Vite dev server exposes two environments by default named `'browser'` and `'node'`. The browser environment runs in client apps that have imported the `/@vite/client` module. The Node environment runs in the same runtime as the Vite server and allows application servers to be used to render requests during dev with full HMR support. We'll discuss later how frameworks and users can create and register new environments. +A Vite dev server exposes two environments by default: `server.clientEnvironment` and `server.ssrEnvironment`. The client environment is a browser environment by default, and the module runner is implemented by importing the virtual module `/@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. We'll discuss later how frameworks and users can change the environment types for the default client and SSR environments, or register new environments (for example to have a separate module graph for RSC). The available environments can be accessed using the `server.environments` array: @@ -92,7 +92,7 @@ interface TransformResult { 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. -But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.environment('browser').transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. +But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.clientEnvironment.transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. :::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. @@ -116,7 +116,7 @@ class ModuleRunner { In the previous iteration, we had `executeUrl` and `executeEntryPoint` methods - they are now merged into a single `import` method. If you want to opt-out of the HMR support, create a runner with `hmr: false` flag. ::: -The Node module runner instance is accessible through `server.nodeModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.nodeModuleRunner` and `server.environment('node')` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. +The default SSR Node module runner instance is accessible through `server.ssrModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.ssrModuleRunner` and `server.ssrEnvironment` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. ```js app.use('*', async (req, res, next) => { @@ -133,9 +133,7 @@ app.use('*', async (req, res, next) => { // 3. Load the server entry. import(url) automatically transforms // ESM source code to be usable in Node.js! There is no bundling // required, and provides full HMR support. - const { render } = await server.nodeModuleRunner.import( - '/src/entry-server.js', - ) + const { render } = await server.ssrModuleRunner.import('/src/entry-server.js') // 4. render the app HTML. This assumes entry-server.js's exported // `render` function calls appropriate framework SSR APIs, @@ -154,7 +152,7 @@ app.use('*', async (req, res, next) => { One of the objectives of this proposal is to allow users to swap Vite's default SSR environment. Out-of-the-box, Vite will use a node environment running on the same process as the server. But a user may want to swap it for a workerd environment. -Vite could expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.nodeModuleRunner`, the example above would be written as: +Vite could expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.ssrModuleRunner`, the example above would be written as: ```js // 3. Load the server entry, with full HMR support. @@ -276,31 +274,9 @@ A plugin could use the `environment` instance to: - Only apply logic for certain environments. - Change the way they work depending on the configuration for the environment, which can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. -:::info environment in hooks - -Using the `environment` string in the hooks doesn't read that well. It isn't clear what should be the name used for a variable when the environment is used in several places in the hook. It could probably be `serverEnvironment`: - -```js -const serverEnvironment = server.environment(environment) -if ( - serverEnvironment.config.noExternal === true || - serverEnvironment.moduleGraph.getModuleById(id) -) { - // ... -} -``` - -We could also pass an environment object that has `{ name, config }`. In a previous iteration, the environment instance was passed directly as a parameter but we also need to pass the `environment` name during build time to hooks. - -Or we could pass to the hooks both `{ environmentName, serverEnvironment }` to avoid cluttering every hook with `const serverEnvironment = server.environment(environment)`. Check out the build section later on. If we explore having a `ViteBuilder` that is aware of environments (and can build them all). We could pass `{ environmentName, serverEnvironment, builderEnvironment }`. One of the instances will always be undefined in this case. I think this is more comfortable to use compared to a single `{ environment: server environment | builder environment }` instance. - -We could also make the environment name or common environment object accessible using the plugin hook context with `this.serverEnvironment`. - -::: - ## Separate module graphs -Vite currently has a mixed browser and ssr/node module graph. Given an unprocessed or invalidated node, it isn't possible to know if it corresponds to the browser, 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 browser and ssr environment for each module node. A module node also has `transformResult` and `ssrTransformResult`. +Vite currently has 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`. In this proposal, each environment has its module graph (and a backward compatibility layer will be implemented to give time to the ecosystem to migrate). 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. @@ -392,51 +368,73 @@ export class ModuleGraph { ## Creating new environments -One of the goals of this feature is to provide a customizable API to process and run code. A Vite dev server provides browser and node environments out of the box, but users can build new environments using the exposed primitives. +One of the goals of this feature is to provide a customizable API to process and run code. Users can create new environment types using the exposed primitives. ```ts -import { createDevEnvironment } from 'vite' +import { DevEnvironment } from 'vite' -const environment = new DevEnvironment({ - name: 'workerd', - config: { - resolve: { conditions: ['custom'] } - }, - // TBD - run(url) { - dispatchModuleRunInWorkerd(url) - } -}) => DevEnvironment +function createWorkerdDevEnvironment(server: ViteDevServer, name: string, config?: DevEnvironmentConfig) { + const workerdModuleRunner = /* ... */ + const hot = /* ... */ + + const workerdDevEnvironment = new DevEnvironment(server, name, { + config: { + resolve: { conditions: ['custom'] }, + ...config, + }, + hot, + }) + return workerdDevEnvironment +} +``` + +Then users can create a workerd environment to do SSR using: + +```js +const ssrEnvironment = createWorkerdEnvironment(server, 'ssr') ``` ## Environment Configuration -All environments share the Vite server configuration, but certain options can be overriden per environment. +Environments are explicitely configured with the `environments` config option. ```js export default { - resolve: { - conditions: [], // shared by all environments - }, environments: [ { - name: 'browser', + name: 'client', resolve: { - conditions: [], // override for the browser environment + conditions: [], // configure for the default Client environment }, }, { - name: 'node', - optimizeDeps: {}, // override for the node environment + name: 'ssr', + optimizeDeps: {}, // configure for the default SSR environment }, { - name: 'workerd', - noExternal: true, // override for a third-party environment + name: 'rsc', + noExternal: true, // configure for a different environment }, ], } ``` +But Vite's user config extends from a environment config, letting users configure the Client environment directly with top level properties as a shortcut. This catters to the common use case of configuring a Vite client only app. +The SSR environment can also be configured using the `ssr` top level property. In a typical SSR Vite app, the user config will look like: + +```js +export default { + resolve: { + conditions: [], // configure the default Client environment (shortcut) + }, + ssr: { + resolve: { + conditions: [], // configure the default SSR environment (shortcut) + }, + }, +} +``` + The `EnvironmentConfig` interface exposes all the per-environment options. There are `SharedEnvironmentConfig` that apply to both `build` and `dev` environments, like `resolve`. And there are `DevOptions` and `BuildOptions` ```ts @@ -446,10 +444,11 @@ interface EnvironmentConfig extends SharedEnvironmentConfig { } ``` -The `UserConfig` interface extends from `EnvironmentConfig`. Environment specific options defined at the root level of user config are used as the default for all environments. A user can use the `environments` record to override default options for any environment. +As we explained, the `UserConfig` interface extends from `EnvironmentConfig`. Environment specific options defined at the root level of user config are used for the default client environment. The `ssr` property is also of type `EnvironmentConfig`. And environments can be configured explicitely using the `environments` array. The Client and SSR environments, are always present, even if an empty array is set to `environments`. ```ts interface UserConfig extends EnvironmentConfig { + ssr: EnvironmentConfig environments: (EnvironmentConfig & { name: string })[] // other options } @@ -465,10 +464,10 @@ export default { { name: 'rsc', dev: { - create: (server) => new NodeDevEnvironment(server), + create: (server) => createNodeDevEnvironment(server), }, build: { - create: (builder) => new NodeBuildEnvironment(builder), + create: (builder) => createNodeBuildEnvironment(builder), outDir: '/dist/rsc', }, }, @@ -479,7 +478,7 @@ export default { Environment providers like Workerd, can expose an environment configurator for the most common case of using the same runtime for both dev and build environments. The default environment options can also be set so the user doesn't need to do it. ```js -function workedEnvironment(userConfig) { +function createWorkedEnvironment(userConfig) { return mergeConfig( { resolve: { @@ -489,11 +488,11 @@ function workedEnvironment(userConfig) { }, dev: { createEnvironment: (server, name) => - new WorkerdDevEnvironment(server, name), + createWorkerdDevEnvironment(server, name), }, build: { createEnvironment: (builder, name) => - new WorkerdBuildEnvironment(builder, name), + createWorkerdBuildEnvironment(builder, name), }, }, userConfig, @@ -508,7 +507,7 @@ import { workerdEnvironment } from 'vite-environment-workerd' export default { environments: [ - workerdEnvironment({ + createWorkerdEnvironment({ name: 'rsc', build: { outDir: '/dist/rsc', @@ -518,7 +517,7 @@ export default { } ``` -The environment will be accessible in middlewares or plugin hooks through `server.environment('workerd')`. +The environment will be accessible in middlewares or plugin hooks through `server.environments`. In plugin hooks, the environment instance is passed in the options so they can do conditions depending on the way they are configured. ## `ModuleRunner` @@ -682,11 +681,17 @@ The callback is queued and it will wait for the current update to be resolved be ## Environments during build -Plugin hooks also receive the environment name during build. This replaces the `ssr` boolean we have been passing them so far. +Plugin hooks also receive the environment instance during build. This replaces the `ssr` boolean we have been passing them so far. + +In the CLI, calling `vite build` will build the Client. It is equivalent to calling `vite build --environment=client`. + +The build the SSR server, the `--ssr` shourcut can be used: `vite build --ssr`. This is equivalent to calling `vite build --environment=ssr`. + +Other non-default environments can be build using `vite build --environment=name`. -The Vite CLI would also be updated from `vite build --ssr` to `vite build --environment=node`. Applications can then call build for each environment (for example `vite build --environment=workerd`). +## Building all environments -Calling `vite build --all` will instantiate a `ViteBuilder` (equivalent to a `ViteDevServer`) and build all configured environments. By default the build of environment is runned in series, but a framework or user can configure it using: +Calling `vite build --all` will instantiate a `ViteBuilder` (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` array. A framework or user can further configure how the build tasks are excecuted using: ```js export default { @@ -709,42 +714,22 @@ export interface BuildTask { } ``` -::: info - -If we have a requirement to create environments dynamically, for example to create an environment depending on the folder structure of user projects at startup. We could let frameworks provide a function at the `server` and `builder` level to do so. - -```js -builder: { - configureEnvironments: async (builder, environments) => { - // Dynamically add build environments - } -}, -server: { - configureEnvironments: (server, environments) => { - // Dynamically add dev environments - } -} -``` - -::: - ## Backward Compatibility The current Vite server API will be deprecated but keep working during the next major. -| Before | After | -| :-------------------------------------------: | :---------------------------------------------------: | -| `server.transformRequest(url)` | `server.environment('browser').transformRequest(url)` | -| `server.transformRequest(url, { ssr: true })` | `server.environment('node').tranformRequest(url)` | -| `server.warmupRequest(url)` | `server.environment('browser').warmupRequest(url)` | -| `server.ssrLoadModule(url)` | `server.nodeModuleRunner.import(url)` | -| `server.moduleGraph` | `server.environment(name).moduleGraph` | -| `handleHotUpdate` | `hotUpdate` | -| `server.open(url)` | `server.environment('browser').run(url)` | +| Before | After | +| :-------------------------------------------: | :----------------------------------------------: | +| `server.transformRequest(url)` | `server.clientEnvironment.transformRequest(url)` | +| `server.transformRequest(url, { ssr: true })` | `server.ssrEnvironment.tranformRequest(url)` | +| `server.warmupRequest(url)` | `server.clientEnvironment.warmupRequest(url)` | +| `server.ssrLoadModule(url)` | `TBD` | +| `server.moduleGraph` | `environment.moduleGraph` | +| `handleHotUpdate` | `hotUpdate` | The last one is just an idea. We may want to keep `server.open(url)` around. -The `server.moduleGraph` will keep returning a mixed view of the browser and node module graphs. Proxy module nodes will be returned so all functions keep returning mixed module nodes. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt-in until then when releasing the API as experimental in Vite 5.2. +The `server.moduleGraph` will keep returning a mixed view of the client and ssr module graphs. Backward compatible mixed module nodes will be returned from all previous functions. The same scheme is used for the module nodes passed to `handleHotUpdate`. This is the most difficult change to get right regarding backward compatibility. We may need to accept small breaking changes when we release the API in Vite 6, making it opt-in until then when releasing the API as experimental in Vite 5.2. ## Open Questions and Alternatives @@ -754,12 +739,8 @@ Names for concepts and the API are the best we could currently find, which we sh ### ModuleLoader vs Environment -Instead of `DevEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environment('browser')` would be `server.moduleLoader('browser')`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. +Instead of `DevEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.clientEnvironment` would be `server.clientModuleLoader`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok, but it is already a stretch. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime also didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. ### Runtime vs Environment We also discussed naming runtime to the concept we call environment in this proposal. We decided to go with Environment because a Runtime refers to node, bun, deno, workerd, a browser. But we need to be able to define two different module execution "environments" for the same runtime. For example SSR and RSC environments, both running in the same node runtime. - -### Server and Client - -We could also call `DevEnvironment` a `ServerEnvironment`, and the `ModuleRunner` in the associated runtime a `ClientEnvironment`. Or some variation using Server and Client in the names. We discarded these ideas because there are already many things that are a "server" (the vite dev server, the HTTP server, etc), and client is also used right now to refer to the browser (as in `clientImportedModules`). From 57bbe170b649df384182e12fff21bd7ca3d7f73c Mon Sep 17 00:00:00 2001 From: patak Date: Fri, 22 Mar 2024 17:56:53 +0100 Subject: [PATCH 29/41] docs: reflect latest changes --- docs/guide/api-vite-environment.md | 320 ++++++++++++++--------------- 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index b3835007b28aa5..9171fdf202c6d0 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -14,14 +14,18 @@ All these environments share Vite's HTTP server, middlewares, and Web Socket. Th ## Using environments in the Vite server -A Vite dev server exposes two environments by default: `server.clientEnvironment` and `server.ssrEnvironment`. The client environment is a browser environment by default, and the module runner is implemented by importing the virtual module `/@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. We'll discuss later how frameworks and users can change the environment types for the default client and SSR environments, or register new environments (for example to have a separate module graph for RSC). +A Vite dev server exposes two environments by default: a Client environment and a SSR environment. The client environment is a browser environment by default, and the module runner is implemented by importing the virtual module `/@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. We'll discuss later how frameworks and users can change the environment types for the default client and SSR environments, or register new environments (for example to have a separate module graph for RSC). -The available environments can be accessed using the `server.environments` array: +The available environments can be accessed using `server.environments`: ```js -server.environments.forEach((environment) => log(environment.name)) +server.environments.client.transformRequest(url) + +console.log(server.environments.ssr.moduleGraph) ``` +Normally, the current `environment` 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. + An dev environment is an instance of the `DevEnvironment` class: ```ts @@ -52,7 +56,7 @@ class DevEnvironment { * global scope are taken as defaults for all environments, and can * be overridden (resolve conditions, external, optimizedDeps) */ - config: ResolvedEnvironmentConfig + config: ResolvedDevEnvironmentConfig constructor(server, { name, hot, run, config }: DevEnvironmentOptions) @@ -92,7 +96,7 @@ interface TransformResult { 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. -But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.clientEnvironment.transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. +But the environment instance can't execute the code itself, as the runtime where the module will be run could be different from the one the Vite server is running in. This is the case for the browser environment. When a html is loaded in the browser, its scripts are executed triggering the evaluation of the entire static module graph. Each imported URL generates a request to the Vite server to get the module code, which ends up handled by the Transform Middleware by calling `server.environments.client.transformRequest(url)`. The connection between the environment instance in the server and the module runner in the browser is carried out through HTTP in this case. :::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. @@ -150,129 +154,9 @@ app.use('*', async (req, res, next) => { ## Environment agnostic SSR -One of the objectives of this proposal is to allow users to swap Vite's default SSR environment. Out-of-the-box, Vite will use a node environment running on the same process as the server. But a user may want to swap it for a workerd environment. - -Vite could expose a `server.ssrEnvironment` so all frameworks can use it and allow them to define what environment type should be used for it. Ideally, instead of using `server.ssrModuleRunner`, the example above would be written as: - -```js -// 3. Load the server entry, with full HMR support. -// Only functions that accepts serializable params and results are supported. -const { render } = await server.ssrEnvironment.import('/src/entry-server.js') - -// 4. render the app HTML. -const appHtml = await render(url) -``` - -`import(url)` would return RPC wrappers for `entry-server` exported functions, so that this code is compatible with both node and workerd environments. - -A `environment.import(url): RPC exports` may be difficult to implement across all environments. So it isn't part of the initial proposal. Given that a lot of projects in the ecosystem end up re-implementating a RPC scheme, we could add it later as a feature that can be supported by a subset of all environments and promote its use only for use cases that don't target universal runtime support. For example, for tools using Vite that are intended to run in a node like environment and want to use a worker thread environment like Vitest. - -In this proposal, environments expose a `environment.run(url): void` function to request running the url in the associated module runner. - -## Plugins and environments - -The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. - -### The `hotUpdate` hook - -- **Type:** `(ctx: HotContext) => Array | void | Promise | void>` -- **See also:** [HMR API](./api-hmr) - -The `hotUpdate` hook allows plugins to perform custom HMR update handling for a given environment. When a file changes, the HMR algorithm is run for each environment in series according to the order in `server.environments`, so the `hotUpdate` hook will be called multiple times. The hook receives a context object with the following signature: - -```ts -interface HotContext { - file: string - timestamp: number - environment: string - modules: Array - read: () => string | Promise - server: ViteDevServer -} -``` - -- `environment` is the module execution environment where a file update is currently being processed. - -- `modules` is an array of modules in this environment that are affected by the changed file. It's an array because a single file may map to multiple served modules (e.g. Vue SFCs). - -- `read` is an async read function that returns the content of the file. This is provided because, on some systems, the file change callback may fire too fast before the editor finishes updating the file, and direct `fs.readFile` will return empty content. The read function passed in normalizes this behavior. - -The hook can choose to: - -- Filter and narrow down the affected module list so that the HMR is more accurate. - -- Return an empty array and perform a full reload: - - ```js - hotUpdate({ environment, modules, timestamp }) { - if (environment !== 'browser') - return - - const serverEnvironment = server.environment(environment) - - serverEnvironment.hot.send({ type: 'full-reload' }) - // Invalidate modules manually - const invalidatedModules = new Set() - for (const mod of modules) { - serverEnvironment.moduleGraph.invalidateModule( - mod, - invalidatedModules, - timestamp, - true - ) - } - return [] - } - ``` - -- Return an empty array and perform complete custom HMR handling by sending custom events to the client: - - ```js - hotUpdate({ environment }) { - if (environment !== 'browser') - return - - server.environment(environment).hot.send({ - type: 'custom', - event: 'special-update', - data: {} - }) - return [] - } - ``` - - Client code should register the corresponding handler using the [HMR API](./api-hmr) (this could be injected by the same plugin's `transform` hook): - - ```js - if (import.meta.hot) { - import.meta.hot.on('special-update', (data) => { - // perform custom update - }) - } - ``` - -### Using `apply` - -In the examples of the previous section, we used a guard in the `hotUpdate` hook to only process updates from the browser environment. If a plugin is specific to only some of the available environments, `apply` can be used to avoid guarding each hook and improve performance. - -```js -function nodeOnlyPlugin() { - return { - name: 'node-only-plugin', - apply: ({ environment }) => environment === 'node', - // unguarded hooks... - } -} -``` - -### Accessing the current environment in hooks - -The `environment` name is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. - -A plugin could use the `environment` instance to: - -- Only apply logic for certain environments. -- Change the way they work depending on the configuration for the environment, which can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. +::: info +It isn't clear yet what APIs Vite should provide to cover the most common SSR use cases. We are thinking on releasing the Environment API without an official way to do environment agnostic SSR to let the ecosystem explore common patterns first. +::: ## Separate module graphs @@ -404,33 +288,27 @@ export default { { name: 'client', resolve: { - conditions: [], // configure for the default Client environment + conditions: [], // configure the Client environment }, }, { name: 'ssr', - optimizeDeps: {}, // configure for the default SSR environment + optimizeDeps: {}, // configure the SSR environment }, { name: 'rsc', - noExternal: true, // configure for a different environment + noExternal: true, // configure a custom environment }, ], } ``` -But Vite's user config extends from a environment config, letting users configure the Client environment directly with top level properties as a shortcut. This catters to the common use case of configuring a Vite client only app. -The SSR environment can also be configured using the `ssr` top level property. In a typical SSR Vite app, the user config will look like: +Vite's user config also extends from a environment config, letting users add defaults for all environments at the root level. This is quite useful for the common use case of configuring a Vite client only app, that can be done without going through `environments.client`. ```js export default { resolve: { - conditions: [], // configure the default Client environment (shortcut) - }, - ssr: { - resolve: { - conditions: [], // configure the default SSR environment (shortcut) - }, + conditions: [], // configure a default for all environments }, } ``` @@ -444,25 +322,29 @@ interface EnvironmentConfig extends SharedEnvironmentConfig { } ``` -As we explained, the `UserConfig` interface extends from `EnvironmentConfig`. Environment specific options defined at the root level of user config are used for the default client environment. The `ssr` property is also of type `EnvironmentConfig`. And environments can be configured explicitely using the `environments` array. The Client and SSR environments, are always present, even if an empty array is set to `environments`. +As we explained, the `UserConfig` interface extends from `EnvironmentConfig`. Environment specific options defined at the root level of user config are used for the default client environment. And environments can be configured explicitely using the `environments` array. The Client and SSR environments, are always present, even if an empty object is set to `environments`. ```ts interface UserConfig extends EnvironmentConfig { - ssr: EnvironmentConfig - environments: (EnvironmentConfig & { name: string })[] + environments: Record // other options } ``` -## Registering environments +::: info + +The `ssr` top level property has many options in common with `EnvironmentConfig`. This option was created for the same use case as `environments` but only allowed configuration of a small number of options. We're going to deprecate it in favour of a unified way to define environment configuration. + +::: + +## Custom environment instances To register a new dev or build environment, you can use a `create` function: ```js export default { - environments: [ - { - name: 'rsc', + environments: { + rsc: {, dev: { create: (server) => createNodeDevEnvironment(server), }, @@ -471,10 +353,12 @@ export default { outDir: '/dist/rsc', }, }, - ], + }, } ``` +The environment will be accessible in middlewares or plugin hooks through `server.environments`. In plugin hooks, the environment instance is passed in the options so they can do conditions depending on the way they are configured. + Environment providers like Workerd, can expose an environment configurator for the most common case of using the same runtime for both dev and build environments. The default environment options can also be set so the user doesn't need to do it. ```js @@ -506,9 +390,13 @@ Then the config file can be writen as import { workerdEnvironment } from 'vite-environment-workerd' export default { - environments: [ - createWorkerdEnvironment({ - name: 'rsc', + environments: { + ssr: createWorkerdEnvironment({ + build: { + outDir: '/dist/ssr', + }, + }), + rsc: createWorkerdEnvironment({ build: { outDir: '/dist/rsc', }, @@ -517,7 +405,119 @@ export default { } ``` -The environment will be accessible in middlewares or plugin hooks through `server.environments`. In plugin hooks, the environment instance is passed in the options so they can do conditions depending on the way they are configured. +In this case we see how a Workerd environment can be set for both the default SSR environment and for a new custom RSC environment. + +## Plugins and environments + +### Accessing the current environment in hooks + +The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. The `environment` instance is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. + +A plugin could use the `environment` instance to: + +- Only apply logic for certain environments. +- Change the way they work depending on the configuration for the environment, which can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. + +### Registering new environments using hooks + +Plugins can add new environments in the `config` hook: + +```ts + config(config: UserConfig) { + config.environments.rsc ??= {} + } +``` + +An empty object is enough to register the environment, default values from the root level environment config. + +### Configuring environment using hooks + +While the `config` hook is running, the complete list of environments isn't yet known and the environments can be affected by both the default values from the root level environment config or explicitely through the `config.environments` record. +Plugins should set default values using the `config` hook. To configure each environment, they can use the new `configEnvironment` hook. This hook is called for each environment with its partially resolved config including resolution of final defaults. + +```ts + configEnvironment(name: string, config: EnvironmentConfig) { + if (name === 'rsc') { + config.resolve.conditions = // ... +``` + +### The `hotUpdate` hook + +- **Type:** `(ctx: HotContext) => Array | void | Promise | void>` +- **See also:** [HMR API](./api-hmr) + +The `hotUpdate` hook allows plugins to perform custom HMR update handling for a given environment. When a file changes, the HMR algorithm is run for each environment in series according to the order in `server.environments`, so the `hotUpdate` hook will be called multiple times. The hook receives a context object with the following signature: + +```ts +interface HotContext { + file: string + timestamp: number + environment: string + modules: Array + read: () => string | Promise + server: ViteDevServer +} +``` + +- `environment` is the module execution environment where a file update is currently being processed. + +- `modules` is an array of modules in this environment that are affected by the changed file. It's an array because a single file may map to multiple served modules (e.g. Vue SFCs). + +- `read` is an async read function that returns the content of the file. This is provided because, on some systems, the file change callback may fire too fast before the editor finishes updating the file, and direct `fs.readFile` will return empty content. The read function passed in normalizes this behavior. + +The hook can choose to: + +- Filter and narrow down the affected module list so that the HMR is more accurate. + +- Return an empty array and perform a full reload: + + ```js + hotUpdate({ environment, modules, timestamp }) { + if (environment !== 'browser') + return + + const serverEnvironment = server.environment(environment) + + serverEnvironment.hot.send({ type: 'full-reload' }) + // Invalidate modules manually + const invalidatedModules = new Set() + for (const mod of modules) { + serverEnvironment.moduleGraph.invalidateModule( + mod, + invalidatedModules, + timestamp, + true + ) + } + return [] + } + ``` + +- Return an empty array and perform complete custom HMR handling by sending custom events to the client: + + ```js + hotUpdate({ environment }) { + if (environment !== 'browser') + return + + server.environment(environment).hot.send({ + type: 'custom', + event: 'special-update', + data: {} + }) + return [] + } + ``` + + Client code should register the corresponding handler using the [HMR API](./api-hmr) (this could be injected by the same plugin's `transform` hook): + + ```js + if (import.meta.hot) { + import.meta.hot.on('special-update', (data) => { + // perform custom update + }) + } + ``` ## `ModuleRunner` @@ -718,14 +718,14 @@ export interface BuildTask { The current Vite server API will be deprecated but keep working during the next major. -| Before | After | -| :-------------------------------------------: | :----------------------------------------------: | -| `server.transformRequest(url)` | `server.clientEnvironment.transformRequest(url)` | -| `server.transformRequest(url, { ssr: true })` | `server.ssrEnvironment.tranformRequest(url)` | -| `server.warmupRequest(url)` | `server.clientEnvironment.warmupRequest(url)` | -| `server.ssrLoadModule(url)` | `TBD` | -| `server.moduleGraph` | `environment.moduleGraph` | -| `handleHotUpdate` | `hotUpdate` | +| Before | After | +| :-------------------------------------------: | :------------------------------------------------: | +| `server.transformRequest(url)` | `server.environments.client.transformRequest(url)` | +| `server.transformRequest(url, { ssr: true })` | `server.environments.ssr.tranformRequest(url)` | +| `server.warmupRequest(url)` | `server.environments.client.warmupRequest(url)` | +| `server.ssrLoadModule(url)` | `TBD` | +| `server.moduleGraph` | `environment.moduleGraph` | +| `handleHotUpdate` | `hotUpdate` | The last one is just an idea. We may want to keep `server.open(url)` around. @@ -739,7 +739,7 @@ Names for concepts and the API are the best we could currently find, which we sh ### ModuleLoader vs Environment -Instead of `DevEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.clientEnvironment` would be `server.clientModuleLoader`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok, but it is already a stretch. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime also didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. +Instead of `DevEnvironment`, we thought of calling the environment piece inside the Vite Server a `ModuleLoader`. So `server.environments.client` would be `server.moduleLoaders.client`. It has some advantages, `transformRequest(url)` could be renamed to `moduleLoader.load(url)`. We could pass to hooks a `loader` string instead of an `environment` string. `vite build --loader=node` could also be ok, but it is already a stretch. A `ModuleLoader` having a `run()` function that connects it to the `ModuleRunner` in the associated runtime also didn't seem like a good fit though. And `loader` could be confused with a node loader, or with the module loader in the target runtime. ### Runtime vs Environment From f0e9144c5be0d8bdb2373f6d6945b8497c85e47e Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Mon, 25 Mar 2024 15:50:31 +0100 Subject: [PATCH 30/41] feat: add transport docs --- docs/guide/api-vite-environment.md | 74 +++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 9171fdf202c6d0..d9970e6ef4396f 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -583,9 +583,9 @@ export interface ModuleRunnerOptions { */ root: string /** - * A method to get the information about the module. + * A set of methods to communicate with the server. */ - fetchModule: FetchFunction + transport: RunnerTransport /** * 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. @@ -645,6 +645,76 @@ export interface ModuleEvaluator { Vite exports `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](https://tc39.es/ecma262/#sec-createdynamicfunction) to accommodate for new lines added. This is done automatically in the server node environment. If your runner implementation doesn't have this constraint, you should use `fetchModule` (exported from `vite`) directly. +## RunnerTransport + +**Type Signature:** + +```ts +interface RunnerTransport { + /** + * A method to get the information about the module. + */ + fetchModule: FetchFunction +} +``` + +Transport object that communicates with the environment via an RPC or by directly calling the function. By default, you need to pass an object with `fetchModule` method - it can use any type of RPC inside of it, but Vite also exposes `RemoteRunnerTransport` to make the configuration easier. You need to couple it with the `RemoteEnvironmentTransport` instance on the server like in this example where module runner is created in the worker thread: + +::: code-group + +```ts [worker.js] +import { parentPort } from 'node:worker_threads' +import { fileURLToPath } from 'node:url' +import { + ESModulesEvaluator, + ModuleRunner, + RemoteRunnerTransport, +} from 'vite/module-runner' + +const runner = new ModuleRunner( + { + root: fileURLToPath(new URL('./', import.meta.url)), + transport: new RemoteRunnerTransport({ + send: (data) => parentPort.postMessage(data), + onMessage: (listener) => parentPort.on('message', listener), + timeout: 5000, + }), + }, + new ESModulesEvaluator(), +) +``` + +```ts [server.js] +import { BroadcastChannel } from 'node:worker_threads' +import { createServer, RemoteEnvironmentTransport, DevEnvironment } from 'vite' + +function createWorkerEnvironment(server) { + const worker = new Worker('./worker.js') + return new DevEnvironment(server, 'worker', { + runner: { + transport: new RemoteEnvironmentTransport({ + send: (data) => worker.postMessage(data), + onMessage: (listener) => worker.on('message', listener), + }), + }, + }) +} + +await createServer({ + environments: { + worker: { + dev: { + createEnvironment: createWorkerEnvironment, + }, + }, + }, +}) +``` + +::: + +`RemoteRunnerTransport` and `RemoteEnvironmentTransport` are meant to be used together. If you don't use either of them, then you can define your own function to communicate between the runner and the server. + ## ModuleRunnerHMRConnection **Type Signature:** From 0337917a7ba5ef6cd5d916752432671d770cbd8d Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Mon, 25 Mar 2024 15:51:08 +0100 Subject: [PATCH 31/41] fix: update the ssr example --- docs/guide/api-vite-environment.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index d9970e6ef4396f..6a6d0ef74bf066 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -120,9 +120,31 @@ class ModuleRunner { In the previous iteration, we had `executeUrl` and `executeEntryPoint` methods - they are now merged into a single `import` method. If you want to opt-out of the HMR support, create a runner with `hmr: false` flag. ::: -The default SSR Node module runner instance is accessible through `server.ssrModuleRunner`. It isn't part of its associated environment instance because, as we explained before, other environments' module runners could live in a different runtime (for example for the browser, a module runner in a worker thread as used in Vitest, or an edge runtime like workerd). The communication between `server.ssrModuleRunner` and `server.ssrEnvironment` is implemented through direct function calls. Given a Vite server configured in middleware mode as described by the [SSR setup guide](#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. +The default SSR Node module runner is not exposed. You can use `createNodeEnvironment` API with `createServerModuleRunner` together to create a runner that runs code in the same thread, supports HMR and doesn't conflict with the SSR implementation (in case it's been overriden in the config). Given a Vite server configured in middleware mode as described by the [SSR setup guide](/guide/ssr#setting-up-the-dev-server), let's implement the SSR middleware using the environment API. Error handling is omitted. ```js +import { + createServer, + createServerModuleRunner, + createNodeEnvironment, +} from 'vite' + +const server = await createServer({ + server: { middlewareMode: true }, + appType: 'custom', + environments: { + node: { + dev: { + // Default Vite SSR environment can be overriden in the config, so + // make sure you have a Node environment before the request is received. + createEnvironment: createNodeEnvironment, + }, + }, + }, +}) + +const runner = createServerModuleRunner(server.environments.node) + app.use('*', async (req, res, next) => { const url = req.originalUrl @@ -137,7 +159,7 @@ app.use('*', async (req, res, next) => { // 3. Load the server entry. import(url) automatically transforms // ESM source code to be usable in Node.js! There is no bundling // required, and provides full HMR support. - const { render } = await server.ssrModuleRunner.import('/src/entry-server.js') + const { render } = await runner.import('/src/entry-server.js') // 4. render the app HTML. This assumes entry-server.js's exported // `render` function calls appropriate framework SSR APIs, From e64cc64c38990eb79b982d74a00e366764c34b78 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Tue, 26 Mar 2024 22:58:55 +0100 Subject: [PATCH 32/41] docs: update to use this.environment --- docs/guide/api-vite-environment.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 6a6d0ef74bf066..7822aec277d93e 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -433,13 +433,19 @@ In this case we see how a Workerd environment can be set for both the default SS ### Accessing the current environment in hooks -The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. The `environment` instance is passed as a parameter to the `options` of `resolveId`, `load`, and `transform`. +The Vite server has a shared plugin pipeline, but when a module is processed it is always done in the context of a given environment. The `environment` instance is available in the plugin context of `resolveId`, `load`, and `transform`. A plugin could use the `environment` instance to: - Only apply logic for certain environments. - Change the way they work depending on the configuration for the environment, which can be accessed using `environment.config`. The vite core resolve plugin modifies the way it resolves ids based on `environment.config.resolve.conditions` for example. +```ts + transform(code, id) { + console.log(this.enviroment.config.resolve.conditions) + } +``` + ### Registering new environments using hooks Plugins can add new environments in the `config` hook: @@ -474,14 +480,13 @@ The `hotUpdate` hook allows plugins to perform custom HMR update handling for a interface HotContext { file: string timestamp: number - environment: string modules: Array read: () => string | Promise server: ViteDevServer } ``` -- `environment` is the module execution environment where a file update is currently being processed. +- `this.environment` is the module execution environment where a file update is currently being processed. - `modules` is an array of modules in this environment that are affected by the changed file. It's an array because a single file may map to multiple served modules (e.g. Vue SFCs). @@ -494,17 +499,15 @@ The hook can choose to: - Return an empty array and perform a full reload: ```js - hotUpdate({ environment, modules, timestamp }) { - if (environment !== 'browser') + hotUpdate({ modules, timestamp }) { + if (this.environment.name !== 'client') return - const serverEnvironment = server.environment(environment) - - serverEnvironment.hot.send({ type: 'full-reload' }) + this.environment.hot.send({ type: 'full-reload' }) // Invalidate modules manually const invalidatedModules = new Set() for (const mod of modules) { - serverEnvironment.moduleGraph.invalidateModule( + this.environment.moduleGraph.invalidateModule( mod, invalidatedModules, timestamp, @@ -518,11 +521,11 @@ The hook can choose to: - Return an empty array and perform complete custom HMR handling by sending custom events to the client: ```js - hotUpdate({ environment }) { - if (environment !== 'browser') + hotUpdate() { + if (this.environment.name !== 'client') return - server.environment(environment).hot.send({ + this.environment.hot.send({ type: 'custom', event: 'special-update', data: {} From f361bf1ec4f4fbbc7d6f3d9d9fcdd7586950d8c0 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Thu, 28 Mar 2024 08:12:48 +0100 Subject: [PATCH 33/41] chore: remove dead link in sidebar --- docs/.vitepress/config.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 2f65dce9500e9a..653b977eb9e26a 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -280,10 +280,6 @@ export default defineConfig({ text: 'Vite Environment API', link: '/guide/api-vite-environment', }, - { - text: 'Vite Runtime API', - link: '/guide/api-vite-runtime', - }, { text: 'Config Reference', link: '/config/', From d181d168a572ebfba399dc462897e840452f958f Mon Sep 17 00:00:00 2001 From: patak-dev Date: Thu, 28 Mar 2024 08:29:40 +0100 Subject: [PATCH 34/41] chore: update --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 7822aec277d93e..f7efa72796b9fc 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -32,7 +32,7 @@ An dev environment is an instance of the `DevEnvironment` class: class DevEnvironment { /** * Unique identifier for the environment in a Vite server. - * By default Vite exposes 'browser' and 'node' environments. + * By default Vite exposes 'client' and 'ssr' environments. */ name: string /** From 569d8639e6f5319126077382113951e783d33c95 Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Thu, 28 Mar 2024 08:33:44 +0100 Subject: [PATCH 35/41] chore: typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 翠 / green --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index f7efa72796b9fc..784d4444870814 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -366,7 +366,7 @@ To register a new dev or build environment, you can use a `create` function: ```js export default { environments: { - rsc: {, + rsc: { dev: { create: (server) => createNodeDevEnvironment(server), }, From 04ec4fbe6ada7aa3b02d8cd7279d740132c80b66 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Thu, 28 Mar 2024 10:46:26 +0100 Subject: [PATCH 36/41] fix: update workerd example --- docs/guide/api-vite-environment.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 784d4444870814..b033cba0acdb33 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -280,8 +280,12 @@ One of the goals of this feature is to provide a customizable API to process and import { DevEnvironment } from 'vite' function createWorkerdDevEnvironment(server: ViteDevServer, name: string, config?: DevEnvironmentConfig) { - const workerdModuleRunner = /* ... */ const hot = /* ... */ + const connection = /* ... */ + const transport = new RemoteEnvironmentTransport({ + send: (data) => connection.send(data), + onMessage: (listener) => connection.on('message', listener), + }) const workerdDevEnvironment = new DevEnvironment(server, name, { config: { @@ -289,6 +293,9 @@ function createWorkerdDevEnvironment(server: ViteDevServer, name: string, config ...config, }, hot, + runner: { + transport, + }, }) return workerdDevEnvironment } From efdc54312d15d33bd955bc195bb074df596bab28 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Thu, 28 Mar 2024 10:47:17 +0100 Subject: [PATCH 37/41] chore: import RemoteEnvironmentTransport in the example --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index b033cba0acdb33..daff12c852e2fc 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -277,7 +277,7 @@ export class ModuleGraph { One of the goals of this feature is to provide a customizable API to process and run code. Users can create new environment types using the exposed primitives. ```ts -import { DevEnvironment } from 'vite' +import { DevEnvironment, RemoteEnvironmentTransport } from 'vite' function createWorkerdDevEnvironment(server: ViteDevServer, name: string, config?: DevEnvironmentConfig) { const hot = /* ... */ From bdc19b407c47ca11cba89e6f89009d415439d9cb Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:35:26 +0100 Subject: [PATCH 38/41] chore: 5.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 翠 / green --- docs/guide/api-vite-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index daff12c852e2fc..f75c9cf0e99c8c 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -1,7 +1,7 @@ # Vite Environment API :::warning Low-level API -Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". In Vite 5.2 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.3, so make sure to pin the Vite version to `~5.2.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". In Vite 5.3 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.4, so make sure to pin the Vite version to `~5.3.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. ::: A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. In a typical Vite app, an environments will be used for the ES modules served to the client and for the server program that does SSR. An app can do SSR on a Node server, but also on an edge runtime like Workerd. So we can have different types of environments on the same Vite server: browser environments, node environments, and workerd environments to name a few. From cae6e330f66c1b28000f62b1e2f25df829f8f992 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Fri, 5 Apr 2024 16:52:12 +0200 Subject: [PATCH 39/41] chore: update banner --- docs/guide/api-vite-environment.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index f75c9cf0e99c8c..087b996242ce98 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -1,7 +1,15 @@ # Vite Environment API :::warning Low-level API -Initial work for this API was introduced in Vite 5.1 with the name "Vite Runtime API". In Vite 5.3 the API was reviewed and renamed as Vite Environment API. It remains an experimental feature. We are gathering feedback about the revised proposal [here](https://github.com/vitejs/vite/discussions/15774). There will probably be breaking changes to it in Vite 5.4, so make sure to pin the Vite version to `~5.3.0` when using it. This is a low-level API meant for library and framework authors. If your goal is to create an application, make sure to check out the higher-level SSR plugins and tools at [Awesome Vite SSR section](https://github.com/vitejs/awesome-vite#ssr) first. +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 Vite Environment API. This API will be released in Vite 6. You can already test it in the latest `vite@6.0.0-alpha.x` version. + +Resources: + +- [PR for the new API docs](https://github.com/vitejs/vite/pull/16089). +- [Feedback discussion](https://github.com/vitejs/vite/discussions/16358) where we are gathering feedback about the new APIs. +- [Environment API branch](https://github.com/vitejs/vite/pull/16129) where the new API is implemented. + +Feel free to send us PRs against this branch to fix the issues you discover. Please share with us your feedback as you test the proposal. ::: A single Vite dev server can be used to interact with different module execution environments concurrently. We'll use the word environment to refer to a configured Vite processing pipeline that can resolve ids, load, and process source code and is connected to a runtime where the code is executed. 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 code for these modules is sent to the runtimes associated with each environment to be executed. When a module is evaluated, the runtime will request its imported modules triggering the processing of a section of the module graph. In a typical Vite app, an environments will be used for the ES modules served to the client and for the server program that does SSR. An app can do SSR on a Node server, but also on an edge runtime like Workerd. So we can have different types of environments on the same Vite server: browser environments, node environments, and workerd environments to name a few. From 147b053809de7577094cbd965be24c5f2db45f56 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Fri, 5 Apr 2024 21:34:09 +0200 Subject: [PATCH 40/41] docs: buildEnvironments --- docs/guide/api-vite-environment.md | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index 087b996242ce98..e22bb3d493d537 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -801,29 +801,18 @@ Other non-default environments can be build using `vite build --environment=name ## Building all environments -Calling `vite build --all` will instantiate a `ViteBuilder` (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` array. A framework or user can further configure how the build tasks are excecuted using: +Calling `vite build --all` will instantiate a `ViteBuilder` (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: ```js export default { builder: { - runBuildTasks: asnyc (builder, buildTasks) => { - return Promise.all(buildTasks.map( task => task.run() )) + buildEnvironments: asnyc (builder) => { + return Promise.all(Object.values(builder.environments).map( environment => builder.build(environment) )) } } } ``` -A build task implements the `BuildTask` interface: - -```js -export interface BuildTask { - environment: BuildEnvironment - config: ResolvedConfig - run: () => Promise - cancel: () => void -} -``` - ## Backward Compatibility The current Vite server API will be deprecated but keep working during the next major. From 9e2bb57fb70670d4ea783d465e0e0fb600814e7a Mon Sep 17 00:00:00 2001 From: patak <583075+patak-dev@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:21:20 +0200 Subject: [PATCH 41/41] chore: update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément --- docs/guide/api-vite-environment.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/guide/api-vite-environment.md b/docs/guide/api-vite-environment.md index e22bb3d493d537..ee2905b69422b1 100644 --- a/docs/guide/api-vite-environment.md +++ b/docs/guide/api-vite-environment.md @@ -321,22 +321,23 @@ Environments are explicitely configured with the `environments` config option. ```js export default { - environments: [ - { - name: 'client', + environments: { + client: { resolve: { conditions: [], // configure the Client environment }, }, - { - name: 'ssr', - optimizeDeps: {}, // configure the SSR environment + ssr: { + dev: { + optimizeDeps: {}, // configure the SSR environment + }, }, - { - name: 'rsc', - noExternal: true, // configure a custom environment + rsc: { + resolve: { + noExternal: true, // configure a custom environment + }, }, - ], + }, } ```