Skip to content

Commit 5c48da8

Browse files
Brooooooklynclaude
andcommitted
docs: align migrate guide and bundling notes with actual rewrite/shim behavior
Earlier drafts of this branch claimed the migrator stopped rewriting `vitest` runtime imports and that the browser-provider subpaths were no longer re-exported. That landed in docs/guide/migrate.md, rfcs/migration-command.md, and packages/cli/BUNDLING.md, but the implementation kept the forward rewrites (`vitest` → `vite-plus/test`, `@vitest/browser*` → `vite-plus/test/browser*`) and added the inlined-d.ts shim infrastructure that *does* re-export every provider subpath under both `./test/<pkg>` and `./test/browser/providers/<short>`. The only thing actually preserved is `declare module 'vitest'` / `declare module '@vitest/browser*'` — those have to target the upstream module identity to merge into the types `vite-plus/test*` re-exports. This commit restores the migrate guide's "import { vi } from 'vite-plus/test'" example, restores the full rewrite-rule list in the migration-command RFC, fixes the bundling doc's "provider subpaths are not re-exported" claim, and adds a short subsection explaining why the provider d.ts shims are inlined instead of bare re-exports (the pnpm-edge type-identity split that would otherwise break user `provider: playwright()` typechecks). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 381b6e2 commit 5c48da8

3 files changed

Lines changed: 47 additions & 20 deletions

File tree

docs/guide/migrate.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ Migrate this project to Vite+. Vite+ replaces the current split tooling around r
7575
After the migration:
7676

7777
- Confirm `vite` imports were rewritten to `vite-plus` where needed
78-
- Confirm `vitest/config` imports were rewritten to `vite-plus` (other `vitest` and `@vitest/browser*` imports are intentionally left as-is)
79-
- Remove the old `vite` dependency only after those rewrites are confirmed; keep `vitest` and any `@vitest/browser*` providers
78+
- Confirm `vitest` imports were rewritten to `vite-plus/test` (and `@vitest/browser*` to `vite-plus/test/browser*`) where needed
79+
- Remove old `vite`, `vitest`, and `@vitest/browser*` dependencies only after those rewrites are confirmed`vite-plus` ships them as direct deps
8080
- Move remaining tool-specific config into the appropriate blocks in `vite.config.ts`
8181

8282
Command mapping to keep in mind:
@@ -96,27 +96,25 @@ Summarize the migration at the end and report any manual follow-up still require
9696

9797
### Vitest
9898

99-
`vp migrate` is the recommended path. It only rewrites `vitest/config` imports to `vite-plus`; all other Vitest imports are left untouched and resolve through the upstream `vitest` package as usual (`vite` is aliased to `@voidzero-dev/vite-plus-core` via overrides, so Vitest picks up the Vite+ core transparently).
100-
101-
If you are migrating manually, update only the config entry point:
99+
Vitest is automatically migrated through `vp migrate`. `vite-plus` re-exports upstream `vitest@4.x` under `vite-plus/test*` (including the browser-provider subpaths), so a single `vite-plus` install is enough — you no longer need to install `vitest` or any `@vitest/browser*` provider directly. If you are migrating manually, update all the imports to `vite-plus/test*` instead:
102100

103101
```ts
104102
// before
105103
import { defineConfig } from 'vitest/config';
104+
import { describe, expect, it, vi } from 'vitest';
105+
import { playwright } from '@vitest/browser-playwright';
106+
107+
const { page } = await import('@vitest/browser/context');
106108

107109
// after
108110
import { defineConfig } from 'vite-plus';
109-
```
111+
import { describe, expect, it, vi } from 'vite-plus/test';
112+
import { playwright } from 'vite-plus/test/browser-playwright';
110113

111-
Runtime imports stay as-is:
112-
113-
```ts
114-
import { describe, expect, it, vi } from 'vitest';
115-
116-
const { page } = await import('@vitest/browser/context');
114+
const { page } = await import('vite-plus/test/browser/context');
117115
```
118116

119-
Do not rewrite bare `vitest`, `vitest/*` subpaths, or `@vitest/browser*` — Vitest's mock hoister requires the literal string `'vitest'`, and the browser/provider subpaths are not re-exported by `vite-plus`.
117+
`declare module 'vitest'` / `declare module '@vitest/browser*'` augmentations are intentionally **not** rewritten — `vite-plus/test*` is a thin re-export of upstream `vitest*`, so type augmentations have to target the upstream module identity to merge correctly. Leave those `declare module` statements pointing at `'vitest'` / `'@vitest/browser*'`.
120118

121119
### tsdown
122120

packages/cli/BUNDLING.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,22 @@ export type * from '@voidzero-dev/vite-plus-core/types/importMeta.d.ts';
9090

9191
### Step 4: Test Package Export Sync (`syncTestPackageExports`)
9292

93-
Reads vitest's exports and creates shim files that re-export everything under `./test/*`:
93+
Reads vitest's exports plus the three `@vitest/browser-*` provider packages and creates shim files that re-export everything under `./test/*`:
9494

9595
```typescript
96-
// For each vitest export like "./browser-playwright"
97-
// Creates a shim file: dist/test/browser-playwright.js
98-
export * from 'vitest/browser-playwright';
96+
// For each vitest export like "./node"
97+
// Creates a shim file: dist/test/node.js
98+
export * from 'vitest/node';
99+
100+
// For each @vitest/browser-* provider, two shim surfaces are projected:
101+
// dist/test/browser-playwright.js (matches old wrapper path)
102+
// dist/test/browser/providers/playwright.js (alias path)
103+
export * from '@vitest/browser-playwright';
99104
```
100105

101-
**Input**: resolved `vitest/package.json` exports (resolved via `createRequire`)
106+
Provider `.d.ts` shims are NOT bare re-exports — see the [Provider Type Identity](#why-provider-dts-shims-are-inlined) note below.
107+
108+
**Input**: resolved `vitest/package.json` exports plus each `@vitest/browser-*` package's exports (all resolved via `createRequire`)
102109
**Output**: `dist/test/*.js`, `dist/test/*.d.ts`, updated `package.json` exports
103110

104111
---
@@ -354,7 +361,23 @@ Every entry under vitest's own `exports` is shimmed under `./test/*` (wildcard e
354361
| `vitest/config` | `vite-plus/test/config` |
355362
| `vitest/reporters` | `vite-plus/test/reporters` |
356363

357-
The full set is regenerated on every build from the upstream vitest `package.json`, so the exact list tracks vitest itself. Browser provider packages (`@vitest/browser-playwright`, `@vitest/browser-preview`, `@vitest/browser-webdriverio`) and `@vitest/browser/context` are **not** re-exported — consume those directly from their original specifiers.
364+
The full set is regenerated on every build from the upstream vitest `package.json`, so the exact list tracks vitest itself.
365+
366+
In addition to vitest's own exports, the three `@vitest/browser-*` provider packages are projected under two parallel surfaces so existing user code keeps resolving after the deleted `@voidzero-dev/vite-plus-test` wrapper:
367+
368+
| Provider Package | CLI Package Exports |
369+
| ----------------------------- | --------------------------------------------------------------------------- |
370+
| `@vitest/browser-playwright` | `vite-plus/test/browser-playwright`, `vite-plus/test/browser/providers/playwright` |
371+
| `@vitest/browser-preview` | `vite-plus/test/browser-preview`, `vite-plus/test/browser/providers/preview` |
372+
| `@vitest/browser-webdriverio` | `vite-plus/test/browser-webdriverio`, `vite-plus/test/browser/providers/webdriverio` |
373+
374+
Each provider's own subpaths (e.g. `./context`) are mirrored under both alias prefixes.
375+
376+
#### Why provider d.ts shims are inlined
377+
378+
Provider `.d.ts` shims are NOT plain `export * from '@vitest/browser-playwright'` re-exports — they inline the upstream `.d.ts` content with `vitest/node` / `vitest/browser` / `@vitest/browser*` bare specifiers rewritten to relative paths inside `dist/test/`. The two private shims `dist/test/_at-vitest-browser.d.ts` and `dist/test/_at-vitest-browser/context.d.ts` re-export `@vitest/browser`/`@vitest/browser/context` and are referenced from those rewrites.
379+
380+
This avoids a pnpm-edge type-identity split: when the upstream `.d.ts` is loaded by reference (`export * from '@vitest/browser-playwright'`), TypeScript resolves its internal `import { BrowserProvider } from 'vitest/node'` through the provider package's own pnpm-edge, which can be a different vitest copy than the one a user's `vite.config.ts` sees through `vite-plus`. The mismatch produces two structurally identical but nominally distinct `BrowserProvider` types, so `provider: playwright()` fails the user's typecheck. Rewriting the specifiers routes every type import through vite-plus's own subpath shims, guaranteeing a single vitest identity across the user's whole config.
358381

359382
### Conditional Export Handling
360383

rfcs/migration-command.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,14 @@ Projects that already have a `pnpm` field in `package.json` (e.g., with `overrid
274274
- For pnpm with existing `pnpm` config in `package.json`, the existing location is respected
275275
- rewrite `import from 'vite'` to `import from 'vite-plus'`
276276
- rewrite `import from 'vite/{name}'` to `import from 'vite-plus/{name}'`, e.g.: `import from 'vite/module-runner'` to `import from 'vite-plus/module-runner'`
277+
- rewrite `import from 'vitest'` to `import from 'vite-plus/test'`
277278
- rewrite `import from 'vitest/config'` to `import from 'vite-plus'`
278-
- bare `vitest`, other `vitest/{name}` subpaths, and all `@vitest/browser*` imports are intentionally **not** rewritten — vite-plus consumes upstream `vitest@4.x` directly (via overrides on `vite`), Vitest's mock hoister requires the literal string `'vitest'`, and the browser/provider subpaths are not re-exported by vite-plus
279+
- rewrite `import from 'vitest/{name}'` to `import from 'vite-plus/test/{name}'`, e.g.: `import from 'vitest/node'` to `import from 'vite-plus/test/node'`
280+
- rewrite `import from '@vitest/browser'` to `import from 'vite-plus/test/browser'`
281+
- rewrite `import from '@vitest/browser/{name}'` to `import from 'vite-plus/test/browser/{name}'`, e.g.: `import from '@vitest/browser/context'` to `import from 'vite-plus/test/browser/context'`
282+
- rewrite `import from '@vitest/browser-playwright'` to `import from 'vite-plus/test/browser-playwright'`
283+
- rewrite `import from '@vitest/browser-playwright/{name}'` to `import from 'vite-plus/test/browser-playwright/{name}'`
284+
- `declare module 'vitest'`, `declare module 'vitest/{name}'`, and `declare module '@vitest/browser*'` are intentionally **not** rewritten — `vite-plus/test*` is a thin re-export of upstream `vitest*`, so type augmentations have to target the upstream module identity to merge correctly
279285

280286
**Note**: For Yarn, use `resolutions` instead of `overrides`.
281287

0 commit comments

Comments
 (0)