Skip to content

Commit 9e24a59

Browse files
authored
fix(browser): support module tracking (#8877)
1 parent e3b7775 commit 9e24a59

File tree

5 files changed

+42
-20
lines changed

5 files changed

+42
-20
lines changed

packages/browser/src/client/public/esm-client-injector.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
(() => {
2-
const moduleCache = new Map();
3-
4-
function wrapModule(module) {
5-
if (typeof module === "function") {
6-
const promise = new Promise((resolve, reject) => {
7-
if (typeof __vitest_mocker__ === "undefined")
8-
return module().then(resolve, reject);
9-
__vitest_mocker__.prepare().finally(() => {
10-
module().then(resolve, reject);
11-
});
12-
});
13-
moduleCache.set(promise, { promise, evaluated: false });
14-
return promise.finally(() => moduleCache.delete(promise));
2+
function wrapModule(moduleCallback) {
3+
if (typeof moduleCallback !== "function") {
4+
return moduleCallback
5+
}
6+
7+
if (typeof __vitest_mocker__ === "undefined" || typeof __vitest_worker__ === 'undefined') {
8+
return moduleCallback()
159
}
16-
return module;
10+
11+
const { evaluatedModules } = __vitest_worker__
12+
const moduleId = crypto.randomUUID()
13+
const viteModule = evaluatedModules.ensureModule(moduleId, moduleId)
14+
15+
viteModule.evaluated = false
16+
viteModule.promise = new Promise((resolve, reject) => {
17+
__vitest_mocker__.prepare().finally(() => {
18+
moduleCallback().then(resolve, reject)
19+
});
20+
});
21+
return viteModule.promise.finally(() => {
22+
viteModule.evaluated = true
23+
viteModule.promise = undefined
24+
25+
evaluatedModules.idToModuleMap.delete(viteModule.id)
26+
evaluatedModules.fileToModulesMap.delete(viteModule.file)
27+
evaluatedModules.urlToIdModuleMap.delete(viteModule.url)
28+
});
1729
}
1830

1931
window.__vitest_browser_runner__ = {
2032
wrapModule,
2133
wrapDynamicImport: wrapModule,
2234
disposeExceptionTracker: () => {},
23-
moduleCache,
2435
cleanups: [],
2536
config: { __VITEST_CONFIG__ },
2637
viteConfig: { __VITEST_VITE_CONFIG__ },

packages/browser/src/client/tester/state.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { BrowserRPC } from '@vitest/browser/client'
22
import type { WorkerGlobalState } from 'vitest'
3+
import { EvaluatedModules } from 'vite/module-runner'
34
import { getBrowserState } from '../utils'
45

56
const config = getBrowserState().config
@@ -30,8 +31,8 @@ const state: WorkerGlobalState = {
3031
},
3132
},
3233
onCleanup: fn => getBrowserState().cleanups.push(fn),
33-
evaluatedModules: getBrowserState().evaluatedModules,
34-
resolvingModules: getBrowserState().resolvingModules,
34+
evaluatedModules: new EvaluatedModules(),
35+
resolvingModules: new Set(),
3536
moduleExecutionInfo: new Map(),
3637
metaEnv: null as any,
3738
rpc: null as any,

packages/browser/src/client/utils.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { VitestRunner } from '@vitest/runner'
2-
import type { EvaluatedModules, SerializedConfig, WorkerGlobalState } from 'vitest'
2+
import type { SerializedConfig, WorkerGlobalState } from 'vitest'
33
import type { IframeOrchestrator } from './orchestrator'
44
import type { CommandsManager } from './tester/tester-utils'
55

@@ -65,8 +65,6 @@ export function ensureAwaited<T>(promise: (error?: Error) => Promise<T>): Promis
6565
export interface BrowserRunnerState {
6666
files: string[]
6767
runningFiles: string[]
68-
resolvingModules: Set<string>
69-
evaluatedModules: EvaluatedModules
7068
config: SerializedConfig
7169
provider: string
7270
runner: VitestRunner

test/browser/src/dynamic.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
window.dispatchEvent(new CustomEvent('module:loaded'))
2+
3+
export {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { expect, test, vi } from 'vitest'
2+
3+
test('can await the end of the dynamic import', async () => {
4+
const _promise = import('../src/dynamic')
5+
const spy = vi.fn()
6+
window.addEventListener('module:loaded', spy)
7+
await vi.dynamicImportSettled()
8+
expect(spy).toHaveBeenCalled()
9+
})

0 commit comments

Comments
 (0)