Commit c75d8df
fix(test): exclude @vitest/browser/context from vendor-aliases to fix missing server export (#1110)
## Summary
Fixes the missing `server` export from `@vitest/browser/context` when
using `@storybook/addon-vitest` with vite-plus.
resolve #1086
## Root Cause
In vitest's browser mode, `@vitest/browser/context` is a **virtual
module**, the `BrowserContext` plugin intercepts the bare specifier in
`resolveId` and returns dynamically generated code (via
`generateContextFile()`) that includes the `server` export with command
RPC proxies, config, platform info, etc.
However, vite-plus injects a `vitest:vendor-aliases` plugin during
re-packaging (in `build.ts`) that maps `@vitest/*` bare specifiers to
static files in the dist directory.
Both plugins use `enforce: 'pre'`, but `vendor-aliases` is registered
**before** `BrowserContext` in the plugin array.
Since Vite executes same-enforce plugins in registration order,
`vendor-aliases` resolves the bare specifier to the static `context.js`
file before `BrowserContext` ever sees it.
The static `context.js` only exports `{ cdp, createUserEvent, locators,
page, utils }` — it does **not** include `server`, because that's
supposed to come from the virtual module.
### Normal flow (plain vitest — no vendor-aliases)
```mermaid
sequenceDiagram
participant Browser
participant ViteServer as Vite Browser Server
participant BC as BrowserContext Plugin<br/>(resolveId)
participant Gen as generateContextFile()
Browser->>ViteServer: import "@vitest/browser/context"
ViteServer->>BC: resolveId("@vitest/browser/context")
BC-->>ViteServer: "\0vitest/browser" (virtual module ID)
ViteServer->>BC: load("\0vitest/browser")
BC->>Gen: generateContextFile()
Gen-->>BC: Dynamic code with server, commands, config...
BC-->>ViteServer: Virtual module source
ViteServer-->>Browser: Module with { server, page, cdp, ... }
```
### Bug flow (vite-plus — vendor-aliases intercepts first)
```mermaid
sequenceDiagram
participant Browser
participant ViteServer as Vite Browser Server
participant VA as vendor-aliases Plugin<br/>(resolveId) ← runs first
participant BC as BrowserContext Plugin<br/>(resolveId) ← never called
Browser->>ViteServer: import "@vitest/browser/context"
ViteServer->>VA: resolveId("@vitest/browser/context")
VA-->>ViteServer: "/path/to/dist/@vitest/browser/context.js" (static file)
Note over BC: resolveId is never called<br/>because vendor-aliases already resolved it
ViteServer-->>Browser: Static file (no server export)
Browser->>Browser: SyntaxError: does not provide<br/>an export named 'server'
```
### Plugin registration order in the browser Vite server
```
1. vitest:vendor-aliases ← enforce:'pre', registered first
2. vitest:browser ← enforce:'pre'
3. vitest:browser:tests ← enforce:'pre'
4. vitest:browser:virtual-module:context (BrowserContext) ← enforce:'pre', registered last
```
## Fix
Exclude `@vitest/browser/context` from the `vendor-aliases` plugin's
`vendorMap` during re-packaging (`build.ts`).
This allows the bare specifier to pass through to the `BrowserContext`
plugin, which correctly returns the virtual module with the `server`
export.
---------
Co-authored-by: MK (fengmk2) <fengmk2@gmail.com>1 parent 8159886 commit c75d8df
2 files changed
Lines changed: 67 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1458 | 1458 | | |
1459 | 1459 | | |
1460 | 1460 | | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
1461 | 1469 | | |
1462 | | - | |
| 1470 | + | |
1463 | 1471 | | |
1464 | 1472 | | |
1465 | 1473 | | |
| |||
0 commit comments