Skip to content

Commit

Permalink
feat: Environment API 1/4 (#1544)
Browse files Browse the repository at this point in the history
* 差分取り込み

* Using environments in the Vite server

* Environment agnostic SSR - Environment Configuration

* ModuleEvaluator まで

* 残り

* 用語統一

* docs: update Environment API guide after beta

* dead links 対応
  • Loading branch information
jay-es authored Sep 12, 2024
1 parent 4e57564 commit 5ad2a62
Show file tree
Hide file tree
Showing 12 changed files with 1,327 additions and 238 deletions.
4 changes: 2 additions & 2 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ export default defineConfig({
link: '/guide/api-javascript',
},
{
text: 'Vite ランタイム API',
link: '/guide/api-vite-runtime',
text: 'Environment API',
link: '/guide/api-environment',
},
{
text: '設定リファレンス',
Expand Down
4 changes: 3 additions & 1 deletion blog/announcing-vite5-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ 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).
::: info
The Vite Runtime API evolved into the Module Runner API, released in Vite 6 as part of the [Environment API](/guide/api-environment).
:::

## Features

Expand Down
122 changes: 122 additions & 0 deletions changes/hotupdate-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# HMR `hotUpdate` Plugin Hook

::: tip Feedback
Give us feedback at [Environment API feedback discussion](https://github.com/vitejs/vite/discussions/16358)
:::

We're planning to deprecate the `handleHotUpdate` plugin hook in favor of [`hotUpdate` hook](/guide/api-environment#the-hotupdate-hook) to be [Environment API](/guide/api-environment.md) aware, and handle additional watch events with `create` and `delete`.

Affected scope: `Vite Plugin Authors`

::: warning Future Deprecation
`hotUpdate` was first introduced in `v6.0`. The deprecation of `handleHotUpdate` is planned for `v7.0`. We don't yet recommend moving away from `handleHotUpdate` yet. If you want to experiment and give us feedback, you can use the `future.removePluginHookHandleHotUpdate` to `"warn"` in your vite config.
:::

## Motivation

The [`handleHotUpdate` hook](/guide/api-plugin.md#handlehotupdate) allows to perform custom HMR update handling. A list of modules to be updated is passed in the `HmrContext`

```ts
interface HmrContext {
file: string
timestamp: number
modules: Array<ModuleNode>
read: () => string | Promise<string>
server: ViteDevServer
}
```

This hook is called once for all environments, and the passed modules have mixed information from the Client and SSR environments only. Once frameworks move to custom environments, a new hook that is called for each of them is needed.

The new `hotUpdate` hook works in the same way as `handleHotUpdate` but it is called for each environment and receives a new `HotUpdateContext` instance:

```ts
interface HotUpdateContext {
type: 'create' | 'update' | 'delete'
file: string
timestamp: number
modules: Array<EnvironmentModuleNode>
read: () => string | Promise<string>
server: ViteDevServer
}
```

The current dev environment can be accessed like in other Plugin hooks with `this.environment`. The `modules` list will now be module nodes from the current environment only. Each environment update can define different update strategies.

This hook is also now called for additional watch events and not only for `'update'`. Use `type` to differentiate between them.

## Migration Guide

Filter and narrow down the affected module list so that the HMR is more accurate.

```js
handleHotUpdate({ modules }) {
return modules.filter(condition)
}

// Migrate to:

hotUpdate({ modules }) {
return modules.filter(condition)
}
```

Return an empty array and perform a full reload:

```js
handleHotUpdate({ server, modules, timestamp }) {
// Invalidate modules manually
const invalidatedModules = new Set()
for (const mod of modules) {
server.moduleGraph.invalidateModule(
mod,
invalidatedModules,
timestamp,
true
)
}
server.ws.send({ type: 'full-reload' })
return []
}

// Migrate to:

hotUpdate({ modules, timestamp }) {
// Invalidate modules manually
const invalidatedModules = new Set()
for (const mod of modules) {
this.environment.moduleGraph.invalidateModule(
mod,
invalidatedModules,
timestamp,
true
)
}
this.environment.hot.send({ type: 'full-reload' })
return []
}
```

Return an empty array and perform complete custom HMR handling by sending custom events to the client:

```js
handleHotUpdate({ server }) {
server.ws.send({
type: 'custom',
event: 'special-update',
data: {}
})
return []
}

// Migrate to...

hotUpdate() {
this.environment.hot.send({
type: 'custom',
event: 'special-update',
data: {}
})
return []
}
```
27 changes: 27 additions & 0 deletions changes/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Breaking Changes

List of breaking changes in Vite including API deprecations, removals, and changes. Most of the changes below can be opt-in using the [`future` option](/config/shared-options.html#future) in your Vite config.

## Planned

These changes are planned for the next major version of Vite. The deprecation or usage warnings will guide you where possible, and we're reaching out to framework, plugin authors, and users to apply these changes.

- _No planned changes yet_

## Considering

These changes are being considered and are often experimental APIs that intend to improve upon current usage patterns. As not all changes are listed here, please check out the [Experimental Label in Vite GitHub Discussions](https://github.com/vitejs/vite/discussions/categories/feedback?discussions_q=label%3Aexperimental+category%3AFeedback) for the full list.

We don't recommend switching to these APIs yet. They are included in Vite to help us gather feedback. Please check these proposals and let us know how they work in your use case in each's linked GitHub Discussions.

- [`this.environment` in Hooks](/changes/this-environment-in-hooks)
- [HMR `hotUpdate` Plugin Hook](/changes/hotupdate-hook)
- [Move to per-environment APIs](/changes/per-environment-apis)
- [SSR using `ModuleRunner` API](/changes/ssr-using-modulerunner)
- [Shared plugins during build](/changes/shared-plugins-during-build)

## Past

The changes below has been done or reverted. They are no longer relevant in the current major version.

- _No past changes yet_
33 changes: 33 additions & 0 deletions changes/per-environment-apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Move to per-environment APIs

::: tip Feedback
Give us feedback at [Environment API feedback discussion](https://github.com/vitejs/vite/discussions/16358)
:::

Multiple APIs from ViteDevServer related to module graph has replaced with more isolated Environment APIs.

- `server.moduleGraph` -> [`environment.moduleGraph`](/guide/api-environment#separate-module-graphs)
- `server.transformRequest` -> `environment.transformRequest`
- `server.warmupRequest` -> `environment.warmupRequest`

Affect scope: `Vite Plugin Authors`

::: warning Future Deprecation
The Environment instance was first introduced at `v6.0`. The deprecation of `server.moduleGraph` and other methods that are now in environments is planned for `v7.0`. We don't recommend moving away from server methods yet. To identify your usage, set these in your vite config.

```ts
future: {
removeServerModuleGraph: 'warn',
removeServerTransformRequest: 'warn',
}
```

:::

## Motivation

// TODO:

## Migration Guide

// TODO:
22 changes: 22 additions & 0 deletions changes/shared-plugins-during-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Shared Plugins during Build

::: tip Feedback
Give us feedback at [Environment API feedback discussion](https://github.com/vitejs/vite/discussions/16358)
:::

// TODO:
See [Shared plugins during build](/guide/api-environment.md#shared-plugins-during-build).

Affect scope: `Vite Plugin Authors`

::: warning Future Default Change
`builder.sharedConfigBuild` was first introduce in `v6.0`. You can set it true to check how your plugins work with a shared config. We're looking for feedback about changing the default in a future major once the plugin ecosystem is ready.
:::

## Motivation

// TODO:

## Migration Guide

// TODO:
21 changes: 21 additions & 0 deletions changes/ssr-using-modulerunner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SSR using `ModuleRunner` API

::: tip Feedback
Give us feedback at [Environment API feedback discussion](https://github.com/vitejs/vite/discussions/16358)
:::

`server.ssrLoadModule` has been replaced by [Module Runner](/guide/api-environment#modulerunner).

Affect scope: `Vite Plugin Authors`

::: warning Future Deprecation
`ModuleRunner` was first introduce in `v6.0`. The deprecation of `server.ssrLoadModule` is planned for a future major. To identify your usage, set `future.removeSrLoadModule` to `"warn"` in your vite config.
:::

## Motivation

// TODO:

## Migration Guide

// TODO:
43 changes: 43 additions & 0 deletions changes/this-environment-in-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# `this.environment` in Hooks

::: tip Feedback
Give us feedback at [Environment API feedback discussion](https://github.com/vitejs/vite/discussions/16358)
:::

Before Vite 6, only two environments were available: `client` and `ssr`. A single `options.ssr` plugin hook argument in `resolveId`, `load` and `transform` allowed plugin authors to differentiate between these two environments when processing modules in plugin hooks. In Vite 6, a Vite application can define any number of named environments as needed. We're introducing `this.environment` in the plugin context to interact with the environment of the current module in hooks.

Affect scope: `Vite Plugin Authors`

::: warning Future Deprecation
`this.environment` was introduced in `v6.0`. The deprecation of `options.ssr` is planned for `v7.0`. At that point we'll start recommending migrating your plugins to use the new API. To identify your usage, set `future.removePluginHookSsrArgument` to `"warn"` in your vite config.
:::

## Motivation

`this.environment` not only allow the plugin hook implementation to know the current environment name, it also gives access to the environment config options, module graph information, and transform pipeline (`environment.config`, `environment.moduleGraph`, `environment.transformRequest()`). Having the environment instance available in the context allows plugin authors to avoid the dependency of the whole dev server (typically cached at startup through the `configureServer` hook).

## Migration Guide

For the existing plugin to do a quick migration, replace the `options.ssr` argument with `this.environment.name !== 'client'` in the `resolveId`, `load` and `transform` hooks:

```ts
import { Plugin } from 'vite'

export function myPlugin(): Plugin {
return {
name: 'my-plugin',
resolveId(id, importer, options) {
const isSSR = options.ssr // [!code --]
const isSSR = this.environment.name !== 'client' // [!code ++]

if (isSSR) {
// SSR specific logic
} else {
// Client specific logic
}
},
}
}
```

For a more robust long term implementation, the plugin hook should handle for [multiple environments](/guide/api-environment.html#accessing-the-current-environment-in-hooks) using fine-grained environment options instead of relying on the environment name.
Loading

0 comments on commit 5ad2a62

Please sign in to comment.