Skip to content

Commit f550119

Browse files
committed
docs(migrate): document user-facing migration rules
1 parent 1dd7b6f commit f550119

2 files changed

Lines changed: 193 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ vite-plus/
4848
- **Package-manager commands**: start at `crates/vite_pm_cli/` and `crates/vite_install/`.
4949
- **Managed Node runtime / shims**: start at `crates/vite_js_runtime/`.
5050
- **Static `vite.config.ts` extraction**: start at `crates/vite_static_config/README.md` and `packages/cli/src/resolve-vite-config.ts`.
51+
- **Migration behavior**: `docs/guide/migrate-rules.md`.
5152
- **Bundled toolchain surfaces**: start with `packages/core/BUNDLING.md`, `packages/cli/BUNDLING.md`, and `packages/test/BUNDLING.md`.
5253
- **Generated project agent guidance**: `packages/cli/AGENTS.md` and `packages/cli/src/utils/agent.ts`; do not edit these when the task is only to improve root repo guidance.
5354
- **Product/repo docs**: root contributor docs live at the repo root and the VitePress site under `docs/` (`docs/guide/`, `docs/config/`); generated agent guidance is separate.

docs/guide/migrate-rules.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# Migration Rules
2+
3+
This guide explains how `vp migrate` updates dependencies, source imports, and
4+
package-manager configuration in existing Vite+ projects. See the
5+
[migration guide](./migrate.md) for the complete command overview.
6+
7+
## Before You Migrate
8+
9+
1. Run `vp upgrade` before migrating an existing Vite+ project. A stale local
10+
CLI does not contain the new migration rules; migration delegates to the
11+
global CLI when the local version is older.
12+
2. Upgrade the project to Vite 8+ and Vitest 4.1+ when necessary.
13+
3. Run `vp migrate` from the workspace root. Use `--no-interactive` in
14+
automated environments.
15+
4. Review every changed manifest, package-manager config, source rewrite, and
16+
generated lockfile.
17+
5. Validate with `vp install`, `vp check`, `vp test`, and `vp build`.
18+
19+
Running the migration again after a successful migration should not produce
20+
another diff.
21+
22+
## Dependency Versions
23+
24+
- `vite-plus` is pinned to the concrete version of the CLI running the
25+
migration, not the `latest` dist-tag.
26+
- The `vite` alias must target `@voidzero-dev/vite-plus-core` from the same
27+
Vite+ release.
28+
- A catalog-backed manifest may contain `catalog:` or an existing named catalog
29+
reference. The referenced catalog value must still be updated to the concrete
30+
toolchain target.
31+
- Preserve deliberate protocol pins such as `workspace:`, `file:`, `link:`,
32+
`npm:`, `github:`, Git URLs, and HTTP URLs.
33+
- Reconcile every workspace package, not only the root manifest. Shared
34+
overrides and catalogs stay at the workspace root; direct peer providers
35+
belong in each package that needs them.
36+
37+
## Dependency Changes
38+
39+
| Dependency | Migration rule |
40+
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41+
| `vite-plus` | Add it where the package is migrated. Re-pin plain ranges to the current concrete target, directly or through a catalog. Preserve deliberate protocol pins. |
42+
| `vite` | Keep or add a real dependency edge where peer resolution requires one, and rewrite that edge plus the shared override/resolution to the matching `@voidzero-dev/vite-plus-core` target. An override rewrites an edge; it does not create one. |
43+
| `vitest` | Remove it in the common node-mode case because `vite-plus` provides it transitively. Keep or add an exact bundled version only in packages with direct Vitest requirements. |
44+
| `@vitest/*` | Align lockstep packages that the project directly lists to the bundled Vitest version. Prefer the package's existing catalog reference when its catalog owns that package; otherwise write the concrete version. |
45+
| `@voidzero-dev/vite-plus-test` | Remove all dependency, override, resolution, and catalog aliases. Rewrite imports to the current `vite-plus/test*` surface. |
46+
47+
### Vite and Overrides
48+
49+
Package-manager overrides do not synthesize dependency edges. This matters most
50+
with pnpm: Vitest has a required `vite` peer, and pnpm can auto-install upstream
51+
Vite when a package that depends on `vite-plus` has no direct `vite` edge. That
52+
creates separate Vite+, Vite, and Vitest peer contexts. Each affected pnpm
53+
workspace package must therefore declare `vite`; the workspace override then
54+
redirects that edge to Vite+ core.
55+
56+
Do not remove a direct `vite` declaration merely because a root override exists.
57+
Normalize existing plain or stale aliases while retaining named catalog
58+
references. A real edge is also required for Bun's peer resolver, and npm
59+
browser-provider layouts may need a top-level edge so nested Vitest packages can
60+
resolve `vite`. After migration, pnpm users should verify that each affected
61+
workspace package has the required direct edge.
62+
63+
### When Vitest Is Directly Required
64+
65+
Keep or add package-local `vitest` at the exact bundled version when any of the
66+
following is true:
67+
68+
- an installed dependency has a non-optional `vitest` peer, whether exact or a
69+
range;
70+
- the package uses Vitest browser mode or an opt-in browser provider;
71+
- source or TypeScript configuration retains an upstream `vitest` reference;
72+
- the package declares `@nuxt/test-utils`; or
73+
- dependency metadata is unavailable and an existing direct `vitest` might be
74+
satisfying an unknown required peer.
75+
76+
`vp migrate` checks installed peer metadata, so integrations such as
77+
`vite-plugin-gherkin` are handled even though their names do not contain
78+
`vitest`.
79+
80+
When a package directly requires Vitest:
81+
82+
- add `vitest` to that package, not indiscriminately to every workspace package;
83+
- use the existing catalog reference when supported, otherwise use the exact
84+
bundled version; and
85+
- keep a matching workspace override or resolution so the graph uses one
86+
Vitest version.
87+
88+
A peer declaration alone does not install Vitest. If a surviving
89+
`peerDependencies.vitest` uses a catalog entry that migration will remove,
90+
resolve it to the public peer range first.
91+
92+
### Vitest Ecosystem Packages
93+
94+
Official current `@vitest/*` packages generally publish in lockstep with
95+
Vitest. Align packages the project directly installs, including
96+
`@vitest/coverage-v8`, `@vitest/coverage-istanbul`, `@vitest/ui`, and
97+
`@vitest/web-worker`.
98+
99+
Catalog handling is package-specific:
100+
101+
- preserve `catalog:` and named `catalog:<name>` dependency references when the
102+
corresponding catalog already defines that package;
103+
- update that catalog entry to the bundled Vitest version; and
104+
- use the concrete bundled version when no catalog owns the package.
105+
106+
Do not align independently versioned or obsolete packages:
107+
108+
- `@vitest/eslint-plugin` has its own version line;
109+
- `@vitest/coverage-c8` stopped at an older release and has no Vitest 4 version;
110+
and
111+
- third-party `vitest-*` integrations keep their own compatible package
112+
versions, although their required Vitest peer may require direct provisioning.
113+
114+
The base `@vitest/browser` runtime and `@vitest/browser-preview` are bundled by
115+
Vite+ and should be removed as direct dependencies. The Playwright and
116+
WebdriverIO providers remain opt-in: keep or add the provider at the bundled
117+
Vitest version and ensure its `playwright` or `webdriverio` peer is installed.
118+
119+
Object-valued nested npm and Bun overrides are preserved because they are
120+
user-defined scopes rather than scalar version pins.
121+
122+
## Source Rewrite Rules
123+
124+
- Rewrite ordinary `vitest` and `vitest/*` imports to `vite-plus/test*`.
125+
- Rewrite scoped browser imports to the corresponding
126+
`vite-plus/test/browser*` exports and provision opt-in providers when needed.
127+
- Leave existing `vite-plus/test*` imports unchanged.
128+
- Do not rewrite `declare module 'vitest'` or
129+
`declare module '@vitest/browser*'`. Module augmentation must retain the
130+
upstream module identity.
131+
- Retained references such as `compilerOptions.types`, `require.resolve`,
132+
`import.meta.resolve`, and `vitest/package.json` require package-local Vitest.
133+
- In a package that declares `@nuxt/test-utils`, preserve every `vitest` and
134+
`vitest/*` module specifier package-wide. Its transform requires the upstream
135+
identity and can otherwise inject a duplicate `vi` import. This exception
136+
does not apply to sibling packages or scoped `@vitest/browser*` imports.
137+
138+
The `prefer-vite-plus-imports` lint rule follows the same Nuxt exception, so
139+
lint autofix preserves these imports.
140+
141+
## Package-Manager Rules
142+
143+
### pnpm
144+
145+
- pnpm 10.6.2+ uses `pnpm-workspace.yaml` as the single source for supported
146+
root settings. Migration moves recognized `package.json#pnpm` fields there,
147+
including overrides, peer rules, patch settings, package extensions,
148+
architecture and build policy, audit/update configuration, and configuration
149+
dependencies. It removes the `pnpm` object when it becomes empty and preserves
150+
unknown keys that may belong to other tooling.
151+
- Before pnpm 10.6.2, migration retains these settings in
152+
`package.json#pnpm`. General workspace-setting support started in pnpm 10.5.0,
153+
but overrides required 10.5.1 and `peerDependencyRules` required 10.6.2. pnpm
154+
11 no longer reads the legacy package.json settings.
155+
- Migration keeps dependency references, default and named catalogs, overrides,
156+
and `peerDependencyRules` consistent.
157+
- Each package whose `vite-plus`/Vitest peer context would otherwise install
158+
upstream Vite needs a direct `vite` edge.
159+
- Unrelated selector-shaped and object-valued overrides are preserved.
160+
161+
### npm
162+
163+
- Migration normalizes direct aliases before adding the matching override so
164+
npm does not fail with `EOVERRIDE`.
165+
- When changing a real Vite installation to the core alias, remove stale Vite
166+
install and lockfile state before reinstalling.
167+
- Add a top-level `vite` edge for opt-in browser-provider layouts when nested
168+
Vitest packages otherwise cannot resolve it.
169+
170+
### Yarn
171+
172+
- Vite+ does not support Plug'n'Play. Detect explicit and implicit PnP before
173+
migration and convert the project to `nodeLinker: node-modules`. Preserve all
174+
unrelated `.yarnrc.yml` settings. `--no-interactive` accepts the conversion;
175+
a process-level `YARN_NODE_LINKER=pnp` must be fixed by the caller.
176+
- Catalog references and user hoisting settings are preserved.
177+
- Migration avoids split Vitest copies under workspace hoisting isolation. It
178+
applies a package-level fix where possible and warns when the isolation
179+
cannot be changed safely.
180+
181+
### Bun
182+
183+
- Preserve existing top-level or workspace catalog locations and named catalog
184+
references.
185+
- Mirror the core alias as a direct `vite` dependency so Bun sees the peer
186+
provider before applying overrides.
187+
- Configure missing-peer suppression in `bunfig.toml` when needed, but do not
188+
overwrite an explicit user `peer` setting.
189+
190+
After updating the manifests and package-manager configuration, migration
191+
reinstalls dependencies once to refresh the lockfile. If installation fails,
192+
migration reports the error and exits with a nonzero status.

0 commit comments

Comments
 (0)