Skip to content

Commit a5e98e6

Browse files
authored
feat: add perEnvironmentWatchChangeDuringDev (#20996)
1 parent 2367195 commit a5e98e6

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

docs/guide/api-environment-plugins.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ The hook can choose to:
146146
147147
## Per-environment State in Plugins
148148
149-
Given that the same plugin instance is used for different environments, the plugin state needs to be keyed with `this.environment`. This is the same pattern the ecosystem has already been using to keep state about modules using the `ssr` boolean as key to avoid mixing client and ssr modules state. A `Map<Environment, State>` can be used to keep the state for each environment separately. Note that for backward compatibility, `buildStart` and `buildEnd` are only called for the client environment without the `perEnvironmentStartEndDuringDev: true` flag.
149+
Given that the same plugin instance is used for different environments, the plugin state needs to be keyed with `this.environment`. This is the same pattern the ecosystem has already been using to keep state about modules using the `ssr` boolean as key to avoid mixing client and ssr modules state. A `Map<Environment, State>` can be used to keep the state for each environment separately. Note that for backward compatibility, `buildStart` and `buildEnd` are only called for the client environment without the `perEnvironmentStartEndDuringDev: true` flag. Same for `watchChange` and the `perEnvironmentWatchChangeDuringDev: true` flag.
150150
151151
```js
152152
function PerEnvironmentCountTransformedModulesPlugin() {

packages/vite/src/node/plugin.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ export interface Plugin<A = any> extends RollupPlugin<A> {
176176
* @experimental
177177
*/
178178
perEnvironmentStartEndDuringDev?: boolean
179+
/**
180+
* Opt-in this plugin into per-environment watchChange during dev.
181+
* For backward-compatibility, the watchChange hook is called only once during
182+
* dev, for the client environment. Plugins can opt-in to be called
183+
* per-environment, aligning with the watchChange hook behavior.
184+
* @experimental
185+
*/
186+
perEnvironmentWatchChangeDuringDev?: boolean
179187
/**
180188
* Enforce plugin invocation tier similar to webpack loaders. Hooks ordering
181189
* is still subject to the `order` property in the hook object.

packages/vite/src/node/server/index.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,19 @@ export interface ServerOptions extends CommonServerOptions {
174174
| false
175175
| ((sourcePath: string, sourcemapPath: string) => boolean)
176176
/**
177-
* Backward compatibility. The buildStart and buildEnd hooks were called only once for all
178-
* environments. This option enables per-environment buildStart and buildEnd hooks.
177+
* Backward compatibility. The buildStart and buildEnd hooks were called only once for
178+
* the client environment. This option enables per-environment buildStart and buildEnd hooks.
179179
* @default false
180180
* @experimental
181181
*/
182182
perEnvironmentStartEndDuringDev?: boolean
183+
/**
184+
* Backward compatibility. The watchChange hook was called only once for the client environment.
185+
* This option enables per-environment watchChange hooks.
186+
* @default false
187+
* @experimental
188+
*/
189+
perEnvironmentWatchChangeDuringDev?: boolean
183190
/**
184191
* Run HMR tasks, by default the HMR propagation is done in parallel for all environments
185192
* @experimental
@@ -802,9 +809,13 @@ export async function _createServer(
802809
file = normalizePath(file)
803810
reloadOnTsconfigChange(server, file)
804811

805-
await pluginContainer.watchChange(file, {
806-
event: isUnlink ? 'delete' : 'create',
807-
})
812+
await Promise.all(
813+
Object.values(server.environments).map((environment) =>
814+
environment.pluginContainer.watchChange(file, {
815+
event: isUnlink ? 'delete' : 'create',
816+
}),
817+
),
818+
)
808819

809820
if (publicDir && publicFiles) {
810821
if (file.startsWith(publicDir)) {
@@ -836,7 +847,11 @@ export async function _createServer(
836847
file = normalizePath(file)
837848
reloadOnTsconfigChange(server, file)
838849

839-
await pluginContainer.watchChange(file, { event: 'update' })
850+
await Promise.all(
851+
Object.values(server.environments).map((environment) =>
852+
environment.pluginContainer.watchChange(file, { event: 'update' }),
853+
),
854+
)
840855
// invalidate module graph cache on file change
841856
for (const environment of Object.values(server.environments)) {
842857
environment.moduleGraph.onFileChange(file)
@@ -1104,6 +1119,7 @@ const _serverConfigDefaults = Object.freeze({
11041119
preTransformRequests: true,
11051120
// sourcemapIgnoreList
11061121
perEnvironmentStartEndDuringDev: false,
1122+
perEnvironmentWatchChangeDuringDev: false,
11071123
// hotUpdateEnvironments
11081124
} satisfies ServerOptions)
11091125
export const serverConfigDefaults: Readonly<Partial<ServerOptions>> =

packages/vite/src/node/server/pluginContainer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,15 @@ class EnvironmentPluginContainer<Env extends Environment = Environment> {
607607
id: string,
608608
change: { event: 'create' | 'update' | 'delete' },
609609
): Promise<void> {
610+
const config = this.environment.getTopLevelConfig()
610611
await this.hookParallel(
611612
'watchChange',
612613
(plugin) => this._getPluginContext(plugin),
613614
() => [id, change],
615+
(plugin) =>
616+
this.environment.name === 'client' ||
617+
config.server.perEnvironmentWatchChangeDuringDev ||
618+
plugin.perEnvironmentWatchChangeDuringDev,
614619
)
615620
}
616621

@@ -1211,7 +1216,8 @@ class PluginContainer {
12111216
}
12121217

12131218
// For backward compatibility, buildStart and watchChange are called only for the client environment
1214-
// buildStart is called per environment for a plugin with the perEnvironmentStartEndDuring dev flag
1219+
// buildStart is called per environment for a plugin with the perEnvironmentStartEndDuringDev flag
1220+
// watchChange is called per environment for a plugin with the perEnvironmentWatchChangeDuringDev flag
12151221

12161222
async buildStart(_options?: InputOptions): Promise<void> {
12171223
return (

0 commit comments

Comments
 (0)