Skip to content
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"typescript": "^5.8.3",
"unplugin-isolated-decl": "^0.14.5",
"unplugin-oxc": "^0.4.8",
"vite": "^6.3.5",
"vite": "^7.1.3",
"vitest": "workspace:*",
"zx": "^8.7.1"
},
Expand Down
18 changes: 14 additions & 4 deletions packages/vitest/src/runtime/moduleRunner/moduleRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@ import type { ExternalModulesExecutor } from '../external-executor'
import type { ModuleExecutionInfo } from './moduleDebug'
import type { VitestModuleEvaluator } from './moduleEvaluator'
import type { VitestTransportOptions } from './moduleTransport'
import { ModuleRunner } from 'vite/module-runner'
import * as viteModuleRunner from 'vite/module-runner'
import { VitestMocker } from './moduleMocker'
import { VitestTransport } from './moduleTransport'

// eslint-disable-next-line ts/ban-ts-comment
// @ts-ignore available since Vite 7.1 https://github.com/vitejs/vite/pull/20260
export type CreateImportMeta = NonNullable<viteModuleRunner.ModuleRunnerOptions['createImportMeta']>
// eslint-disable-next-line ts/ban-ts-comment
// @ts-ignore
export const createNodeImportMeta: CreateImportMeta = viteModuleRunner.createNodeImportMeta

// @ts-expect-error overriding private method
export class VitestModuleRunner extends ModuleRunner {
export class VitestModuleRunner extends viteModuleRunner.ModuleRunner {
public mocker: VitestMocker
public moduleExecutionInfo: ModuleExecutionInfo

constructor(private options: VitestModuleRunnerOptions) {
constructor(private vitestOptions: VitestModuleRunnerOptions) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base class ModuleRunner also has options property, which later accessed for this.options.createImportMeta
https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/module-runner/runner.ts#L342-L343. To avoid crashing the properly, I needed to rename this.

const options = vitestOptions
const transport = new VitestTransport(options.transport)
const evaluatedModules = options.evaluatedModules
super(
Expand All @@ -24,6 +32,7 @@ export class VitestModuleRunner extends ModuleRunner {
hmr: false,
evaluatedModules,
sourcemapInterceptor: 'prepareStackTrace',
createImportMeta: vitestOptions.createImportMeta,
},
options.evaluator,
)
Expand Down Expand Up @@ -56,7 +65,7 @@ export class VitestModuleRunner extends ModuleRunner {
}

public async import(rawId: string): Promise<any> {
const resolved = await this.options.transport.resolveId(rawId)
const resolved = await this.vitestOptions.transport.resolveId(rawId)
if (!resolved) {
return super.import(rawId)
}
Expand Down Expand Up @@ -145,6 +154,7 @@ export interface VitestModuleRunnerOptions {
mocker?: VitestMocker
vm?: VitestVmOptions
spyModule?: typeof import('@vitest/spy')
createImportMeta?: CreateImportMeta
}

export interface VitestVmOptions {
Expand Down
3 changes: 3 additions & 0 deletions packages/vitest/src/runtime/moduleRunner/startModuleRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type vm from 'node:vm'
import type { EvaluatedModules } from 'vite/module-runner'
import type { WorkerGlobalState } from '../../types/worker'
import type { ExternalModulesExecutor } from '../external-executor'
import type { CreateImportMeta } from './moduleRunner'
import fs from 'node:fs'
import { isBuiltin } from 'node:module'
import { isBareImport } from '@vitest/utils'
Expand All @@ -26,6 +27,7 @@ export interface ContextModuleRunnerOptions {
externalModulesExecutor?: ExternalModulesExecutor
state: WorkerGlobalState
spyModule?: typeof import('@vitest/spy')
createImportMeta?: CreateImportMeta
}

const cwd = process.cwd()
Expand Down Expand Up @@ -161,6 +163,7 @@ export function startVitestModuleRunner(options: ContextModuleRunnerOptions): Vi
},
getWorkerState: state,
vm,
createImportMeta: options.createImportMeta,
})

// await moduleRunner.import('/@vite/env')
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/runtime/workers/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ContextModuleRunnerOptions } from '../moduleRunner/startModuleRunn
import { runInThisContext } from 'node:vm'
import * as spyModule from '@vitest/spy'
import { EvaluatedModules } from 'vite/module-runner'
import { createNodeImportMeta } from '../moduleRunner/moduleRunner'
import { startVitestModuleRunner } from '../moduleRunner/startModuleRunner'
import { run } from '../runBaseTests'
import { provideWorkerState } from '../utils'
Expand Down Expand Up @@ -52,6 +53,7 @@ export async function runBaseTests(method: 'run' | 'collect', state: WorkerGloba
state,
evaluatedModules: state.evaluatedModules,
spyModule,
createImportMeta: createNodeImportMeta,
Copy link
Contributor Author

@hi-ogawa hi-ogawa Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it explicitly passed via startVitestModuleRunner since otherwise createNodeImportMeta would break @vitest/web-worker on vm since module.register is not supported there. Such limitation might exist for other custom runner (e.g. cloudflare), so making this as opt-in is probably better.

})
const fileSpecs = ctx.files.map(f =>
typeof f === 'string'
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/runtime/workers/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { distDir } from '../../paths'
import { createCustomConsole } from '../console'
import { ExternalModulesExecutor } from '../external-executor'
import { getDefaultRequestStubs } from '../moduleRunner/moduleEvaluator'
import { createNodeImportMeta } from '../moduleRunner/moduleRunner'
import { startVitestModuleRunner, VITEST_VM_CONTEXT_SYMBOL } from '../moduleRunner/startModuleRunner'
import { provideWorkerState } from '../utils'
import { FileMap } from '../vm/file-map'
Expand Down Expand Up @@ -80,6 +81,7 @@ export async function runVmTests(method: 'run' | 'collect', state: WorkerGlobalS
evaluatedModules: state.evaluatedModules,
state,
externalModulesExecutor,
createImportMeta: createNodeImportMeta,
})

Object.defineProperty(context, VITEST_VM_CONTEXT_SYMBOL, {
Expand Down
Loading
Loading