diff --git a/docs/guide/environment.md b/docs/guide/environment.md index 97543435ef4e..a650895c2e0c 100644 --- a/docs/guide/environment.md +++ b/docs/guide/environment.md @@ -49,6 +49,9 @@ import type { Environment } from 'vitest/runtime' export default { name: 'custom', viteEnvironment: 'ssr', + // optional - set to false when "setupVM" is fast, so vm pools + // do not transform the import graph while it runs + prewarmModules: true, // optional - only if you support "vmForks" or "vmThreads" pools async setupVM() { const vm = await import('node:vm') diff --git a/packages/vitest/src/integrations/env/node.ts b/packages/vitest/src/integrations/env/node.ts index 56ef222a8496..de7dd62d8db8 100644 --- a/packages/vitest/src/integrations/env/node.ts +++ b/packages/vitest/src/integrations/env/node.ts @@ -41,6 +41,7 @@ function populateNodeGlobals() { export default { name: 'node', viteEnvironment: 'ssr', + prewarmModules: false, // this is largely copied from jest's node environment async setupVM() { populateNodeGlobals() diff --git a/packages/vitest/src/runtime/workers/vm.ts b/packages/vitest/src/runtime/workers/vm.ts index 7849497ca169..f989ccde7c68 100644 --- a/packages/vitest/src/runtime/workers/vm.ts +++ b/packages/vitest/src/runtime/workers/vm.ts @@ -37,15 +37,14 @@ export async function runVmTests(method: 'run' | 'collect', state: WorkerGlobalS state.environment = environment // let the server transform this file's import graph while this worker is - // busy importing the environment package (jsdom takes ~0.5s per worker) — - // the server is otherwise idle during that window on a cold start. The - // transforms also land in the `fetchWarmModules` snapshot, so the worker's - // own fetches short-circuit to disk reads. Failures are ignored: the - // worker's own fetch reports them with the proper import context. - rpc.prewarmModuleGraph( - environment.viteEnvironment || environment.name, - ctx.files.map(file => file.filepath), - ).catch(() => {}) + // busy setting up the environment (jsdom takes ~0.5s per worker) — + // the server is otherwise idle during that window on a cold start. + if (environment.prewarmModules !== false) { + rpc.prewarmModuleGraph( + environment.viteEnvironment || environment.name, + ctx.files.map(file => file.filepath), + ).catch(() => {}) + } if (!environment.setupVM) { const envName = ctx.environment.name diff --git a/packages/vitest/src/types/environment.ts b/packages/vitest/src/types/environment.ts index e165bc228948..a5e809dfa653 100644 --- a/packages/vitest/src/types/environment.ts +++ b/packages/vitest/src/types/environment.ts @@ -22,6 +22,14 @@ export interface Environment { * By default, fallbacks to `name`. */ viteEnvironment?: 'client' | 'ssr' | ({} & string) + /** + * Let the server transform the test file's import graph while `setupVM` + * runs. Only worth it when `setupVM` is slow (jsdom, happy-dom): otherwise + * the transforms compete with the worker's own module requests. + * + * @default `true` + */ + prewarmModules?: boolean setupVM?: (options: Record) => Awaitable setup: ( global: any,