vite-plus 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/binding/index.cjs +137 -55
  2. package/binding/index.d.cts +40 -0
  3. package/dist/{agent-C59HKB4Y.js → agent-Cu6-tXIP.js} +2 -2
  4. package/dist/bin.js +5 -5
  5. package/dist/config/bin.js +2 -2
  6. package/dist/{constants-IhOditRA.js → constants-C2dTOTe-.js} +1 -1
  7. package/dist/create/bin.js +84 -65
  8. package/dist/{define-config-DpAPETDf.cjs → define-config-D0mevyb3.cjs} +1 -1
  9. package/dist/{define-config-DAaCa0U_.js → define-config-IgzmnvvV.js} +1 -1
  10. package/dist/define-config.cjs +1 -1
  11. package/dist/define-config.js +1 -1
  12. package/dist/{editor-QOIGtmH4.js → editor-4sjlHmUh.js} +17 -6
  13. package/dist/index.cjs +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/lint-plugins.cjs +1 -1
  16. package/dist/migration/bin.js +6 -6
  17. package/dist/{oxlint-plugin-config-BU42tr8y.js → oxlint-plugin-config-BVqEe9KY.js} +1 -1
  18. package/dist/oxlint-plugin.js +1 -1
  19. package/dist/pack-bin.js +1 -1
  20. package/dist/{package-BB-Jh_z3.js → package-CHH8jWan.js} +1 -1
  21. package/dist/{prompts-CujFOJXu.js → prompts-k14KgthC.js} +1 -1
  22. package/dist/{resolve-vite-config-CHHjsjKJ.js → resolve-vite-config-BqvS2P98.js} +2 -2
  23. package/dist/{resolve-vite-config-6Nox70uP.js → resolve-vite-config-CTOTuqTi.js} +1 -1
  24. package/dist/staged/bin.js +1 -1
  25. package/dist/toolchain.js +7 -7
  26. package/dist/toolchain.json +7 -7
  27. package/dist/{tsconfig-DCtWfQPA.js → tsconfig-C3h9CVTA.js} +2 -2
  28. package/dist/{tsconfig-MXktI3SX.js → tsconfig-euB-GmIE.js} +1 -1
  29. package/dist/version.js +2 -2
  30. package/dist/versions.js +3 -3
  31. package/docs/config/staged.md +1 -2
  32. package/docs/guide/ci.md +28 -31
  33. package/docs/guide/commit-hooks.md +11 -34
  34. package/docs/guide/create.md +1 -2
  35. package/docs/guide/docker.md +20 -68
  36. package/docs/guide/env.md +30 -20
  37. package/docs/guide/global-cli.md +426 -0
  38. package/docs/guide/ide-integration.md +1 -2
  39. package/docs/guide/implode.md +14 -1
  40. package/docs/guide/index.md +37 -34
  41. package/docs/guide/install.md +17 -19
  42. package/docs/guide/lint.md +3 -9
  43. package/docs/guide/local-cli.md +123 -0
  44. package/docs/guide/migrate-rules.md +93 -290
  45. package/docs/guide/migrate.md +5 -48
  46. package/docs/guide/run.md +1 -1
  47. package/docs/guide/troubleshooting.md +3 -8
  48. package/docs/guide/upgrade-project.md +61 -0
  49. package/docs/guide/upgrade.md +17 -62
  50. package/package.json +17 -17
  51. package/docs/guide/installer-env-vars.md +0 -286
@@ -1,52 +1,31 @@
1
1
  # Migration Rules
2
2
 
3
- This reference describes exactly what `vp migrate` does to a project: how it
4
- updates dependencies, rewrites source imports and package scripts, and adjusts
5
- package-manager configuration. See the [migration guide](./migrate.md) for the
6
- command overview and workflow.
3
+ This reference describes exactly what `vp migrate` does to a project: how it updates dependencies, rewrites source imports and package scripts, and adjusts package-manager configuration. See the [migration guide](./migrate.md) for the command overview and workflow.
7
4
 
8
- Except for [Before You Migrate](#before-you-migrate), which lists steps you
9
- take yourself, everything below describes automatic behavior.
5
+ Except for [Before You Migrate](#before-you-migrate), which lists steps you take yourself, everything below describes automatic behavior.
10
6
 
11
7
  ## Before You Migrate
12
8
 
13
- 1. Run `vp upgrade` so the global CLI has the latest migration rules. A stale
14
- local `vite-plus` is not a blocker: when the project's local copy is older,
15
- migration delegates to the global CLI.
9
+ 1. Run `vp upgrade` so the global CLI has the latest migration rules. A stale local `vite-plus` is not a blocker: when the project's local copy is older, migration delegates to the global CLI.
16
10
  2. Upgrade the project to Vite 8+ and Vitest 4.1+ when necessary.
17
- 3. Run `vp migrate` from the workspace root. Use `--no-interactive` in
18
- automated environments.
19
- 4. Review every changed manifest, package-manager config, source rewrite, and
20
- generated lockfile.
11
+ 3. Run `vp migrate` from the workspace root. Use `--no-interactive` in automated environments.
12
+ 4. Review every changed manifest, package-manager config, source rewrite, and generated lockfile.
21
13
  5. Validate with `vp install`, `vp check`, `vp test`, and `vp build`.
22
14
 
23
- Migration is idempotent: running it again after a successful migration should
24
- not produce another diff.
15
+ Migration is idempotent: running it again after a successful migration should not produce another diff.
25
16
 
26
17
  ## Upgrade vs. Full Setup
27
18
 
28
- On a project that already depends on `vite-plus`, `vp migrate` performs an
29
- upgrade only: it updates dependencies and package-manager configuration and
30
- finalizes imports. It does not touch project setup.
19
+ On a project that already depends on `vite-plus`, `vp migrate` performs an upgrade only: it updates dependencies and package-manager configuration and finalizes imports. It does not touch project setup.
31
20
 
32
- - `--full` also runs the setup actions: git hooks, editor config, agent files,
33
- ESLint and Prettier migration, framework shims, the tsconfig `baseUrl` fix,
34
- and the `.nvmrc`/Volta to `.node-version` conversion.
35
- - `--hooks`, `--agent`, and `--editor` opt into a single setup action without
36
- `--full`.
21
+ - `--full` also runs the setup actions: git hooks, editor config, agent files, ESLint and Prettier migration, framework shims, the tsconfig `baseUrl` fix, and the `.nvmrc`/Volta to `.node-version` conversion.
22
+ - `--hooks`, `--agent`, and `--editor` opt into a single setup action without `--full`.
37
23
 
38
- When a default upgrade skips setup actions that would apply, it prints a hint
39
- to run `vp migrate --full`. Fresh (non Vite+) projects always run the full
40
- migration.
24
+ When a default upgrade skips setup actions that would apply, it prints a hint to run `vp migrate --full`. Fresh (non Vite+) projects always run the full migration.
41
25
 
42
26
  ## Pack Configuration
43
27
 
44
- `vp migrate` updates static `pack` objects in `vite.config.*` and exported
45
- objects in `tsdown.config.*` for [tsdown 0.23](https://github.com/rolldown/tsdown/releases/tag/v0.23.0).
46
- This also runs on existing Vite+ projects without `--full`, including workspace
47
- packages. Arrays and direct objects returned by `defineConfig` callbacks are
48
- supported. JSON tsdown configs receive the same updates after they merge into
49
- `vite.config.ts`.
28
+ `vp migrate` updates static `pack` objects in `vite.config.*` and exported objects in `tsdown.config.*` for [tsdown 0.23](https://github.com/rolldown/tsdown/releases/tag/v0.23.0). This also runs on existing Vite+ projects without `--full`, including workspace packages. Arrays and direct objects returned by `defineConfig` callbacks are supported. JSON tsdown configs receive the same updates after they merge into `vite.config.ts`.
50
29
 
51
30
  | Previous option | Updated option |
52
31
  | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
@@ -63,27 +42,13 @@ supported. JSON tsdown configs receive the same updates after they merge into
63
42
  | `dts.cjsReexport` | Removed; tsdown generates CJS declarations separately |
64
43
  | `--public-dir` in `tsdown` or `vp pack` scripts | `--copy` |
65
44
 
66
- Migration preserves the previous defaults by setting `deps.resolveDepSubpath`
67
- to `true` when absent. Enabled ATTW checks receive `profile: 'strict'` when
68
- no profile is set. Explicit values, including `false`, remain unchanged.
45
+ Migration preserves the previous defaults by setting `deps.resolveDepSubpath` to `true` when absent. Enabled ATTW checks receive `profile: 'strict'` when no profile is set. Explicit values, including `false`, remain unchanged.
69
46
 
70
- `noExternal` moves to `deps.alwaysBundle`, preserving matcher expressions,
71
- references, and callback methods. Existing `deps.alwaysBundle` values remain
72
- unchanged.
47
+ `noExternal` moves to `deps.alwaysBundle`, preserving matcher expressions, references, and callback methods. Existing `deps.alwaysBundle` values remain unchanged.
73
48
 
74
- When `external` accompanies either `skipNodeModulesBundle` form, static matchers
75
- and references to local constants move to `inputOptions.external` before
76
- `deps.neverBundle` is set. Constant declarations and references stay intact.
77
- This preserves the original matching rules, including external file paths. Unsupported matchers,
78
- conflicting `inputOptions`, and declaration-specific dependency rules leave the
79
- pack object unchanged and produce a manual-migration warning.
49
+ When `external` accompanies either `skipNodeModulesBundle` form, static matchers and references to local constants move to `inputOptions.external` before `deps.neverBundle` is set. Constant declarations and references stay intact. This preserves the original matching rules, including external file paths. Unsupported matchers, conflicting `inputOptions`, and declaration-specific dependency rules leave the pack object unchanged and produce a manual-migration warning.
80
50
 
81
- The transform does not evaluate configuration code. Objects with spreads,
82
- computed keys, or duplicate keys, and conflicting old and new options require
83
- manual review. Dynamic boolean selectors remain unchanged. Unrelated Vite and
84
- plugin options remain unchanged. Run `vp pack` after migration to check the
85
- result. Node.js requirements, TypeScript module resolution, and programmatic
86
- `build()` return values require separate review.
51
+ The transform does not evaluate configuration code. Objects with spreads, computed keys, or duplicate keys, and conflicting old and new options require manual review. Dynamic boolean selectors remain unchanged. Unrelated Vite and plugin options remain unchanged. Run `vp pack` after migration to check the result. Node.js requirements, TypeScript module resolution, and programmatic `build()` return values require separate review.
87
52
 
88
53
  ## Dependency Rules
89
54
 
@@ -99,216 +64,115 @@ What happens to each toolchain dependency, at a glance:
99
64
 
100
65
  ### Version Selection
101
66
 
102
- - `vite-plus` is pinned to the concrete version of the CLI running the
103
- migration, never the `latest` dist-tag.
104
- - The `vite` alias targets `@voidzero-dev/vite-plus-core` from the same Vite+
105
- release.
106
- - A catalog-backed manifest may contain `catalog:` or a named catalog
107
- reference. Migration keeps the reference and updates the referenced catalog
108
- value to the concrete toolchain target.
109
- - Deliberate protocol pins are preserved: `workspace:`, `file:`, `link:`,
110
- `npm:`, `github:`, Git URLs, and HTTP URLs.
111
- - Migration reconciles every workspace package, not only the root manifest.
112
- Shared overrides and catalogs stay at the workspace root; dependencies that
113
- provide a peer belong in each package that needs them.
67
+ - `vite-plus` is pinned to the concrete version of the CLI running the migration, never the `latest` dist-tag.
68
+ - The `vite` alias targets `@voidzero-dev/vite-plus-core` from the same Vite+ release.
69
+ - A catalog-backed manifest may contain `catalog:` or a named catalog reference. Migration keeps the reference and updates the referenced catalog value to the concrete toolchain target.
70
+ - Deliberate protocol pins are preserved: `workspace:`, `file:`, `link:`, `npm:`, `github:`, Git URLs, and HTTP URLs.
71
+ - Migration reconciles every workspace package, not only the root manifest. Shared overrides and catalogs stay at the workspace root; dependencies that provide a peer belong in each package that needs them.
114
72
 
115
73
  ### Vite and Overrides
116
74
 
117
- Package-manager overrides do not create dependency edges by themselves. Under
118
- pnpm, a package that lists `vite-plus` in `dependencies` or `devDependencies`
119
- but has no `vite` entry anywhere (`dependencies`, `devDependencies`,
120
- `optionalDependencies`, or `peerDependencies`) lets pnpm auto-install upstream
121
- Vite to satisfy Vitest's required `vite` peer, splitting the project across
122
- separate Vite+, Vite, and Vitest instances. To prevent this, `vp migrate` adds
123
- the missing `vite` entry to `devDependencies` of every such package; the
124
- workspace override then redirects it to Vite+ core.
75
+ Package-manager overrides do not create dependency edges by themselves. Under pnpm, a package that lists `vite-plus` in `dependencies` or `devDependencies` but has no `vite` entry anywhere (`dependencies`, `devDependencies`, `optionalDependencies`, or `peerDependencies`) lets pnpm auto-install upstream Vite to satisfy Vitest's required `vite` peer, splitting the project across separate Vite+, Vite, and Vitest instances. To prevent this, `vp migrate` adds the missing `vite` entry to `devDependencies` of every such package; the workspace override then redirects it to Vite+ core.
125
76
 
126
77
  Related rules:
127
78
 
128
- - A direct `vite` declaration is never removed merely because a root override
129
- exists.
79
+ - A direct `vite` declaration is never removed merely because a root override exists.
130
80
  - Plain or stale aliases are normalized; named catalog references are kept.
131
- - Under pnpm the managed override keys use an explicit `@*` range (`vite@*`,
132
- `vitest@*`). pnpm applies an override by replacing the declared spec on every
133
- manifest, importer manifests included. A bare key matches any spec, including
134
- `catalog:`, and `vp up` then rewrites that reference to a concrete version.
135
- The `@*` range keeps the override on the semver ranges that transitive and
136
- peer declarations use. It leaves `catalog:` references to the catalog, which
137
- already resolves them to Vite+ core. Migration re-keys a project that still
138
- holds the bare key, and keeps its named-catalog choice.
139
- - The direct-entry rule above is pnpm-specific. Bun mirrors its core alias as
140
- a direct dependency for its peer resolver, and npm browser-provider layouts
141
- may need a top-level `vite` edge so nested Vitest packages can resolve
142
- `vite`.
81
+ - Under pnpm the managed override keys use an explicit `@*` range (`vite@*`, `vitest@*`). pnpm applies an override by replacing the declared spec on every manifest, importer manifests included. A bare key matches any spec, including `catalog:`, and `vp up` then rewrites that reference to a concrete version. The `@*` range keeps the override on the semver ranges that transitive and peer declarations use. It leaves `catalog:` references to the catalog, which already resolves them to Vite+ core. Migration re-keys a project that still holds the bare key, and keeps its named-catalog choice.
82
+ - The direct-entry rule above is pnpm-specific. Bun mirrors its core alias as a direct dependency for its peer resolver, and npm browser-provider layouts may need a top-level `vite` edge so nested Vitest packages can resolve `vite`.
143
83
 
144
84
  ### When Vitest Is Directly Required
145
85
 
146
- Migration keeps or adds a package-local `vitest` at the exact bundled version
147
- when any of the following is true:
86
+ Migration keeps or adds a package-local `vitest` at the exact bundled version when any of the following is true:
148
87
 
149
- - an installed dependency has a non-optional `vitest` peer, whether exact or a
150
- range;
88
+ - an installed dependency has a non-optional `vitest` peer, whether exact or a range;
151
89
  - the package uses Vitest browser mode or an opt-in browser provider;
152
90
  - source or TypeScript configuration retains an upstream `vitest` reference;
153
91
  - the package declares `@nuxt/test-utils`; or
154
- - dependency metadata is unavailable and an existing direct `vitest` might be
155
- satisfying an unknown required peer.
92
+ - dependency metadata is unavailable and an existing direct `vitest` might be satisfying an unknown required peer.
156
93
 
157
- Detection reads installed peer metadata, so integrations such as
158
- `vite-plugin-gherkin` are handled even though their names do not contain
159
- `vitest`.
94
+ Detection reads installed peer metadata, so integrations such as `vite-plugin-gherkin` are handled even though their names do not contain `vitest`.
160
95
 
161
96
  When a package qualifies, migration:
162
97
 
163
- - adds `vitest` to that package, not indiscriminately to every workspace
164
- package;
165
- - uses the existing catalog reference when supported, otherwise the exact
166
- bundled version; and
167
- - keeps a matching workspace override or resolution so the graph resolves a
168
- single Vitest version.
98
+ - adds `vitest` to that package, not indiscriminately to every workspace package;
99
+ - uses the existing catalog reference when supported, otherwise the exact bundled version; and
100
+ - keeps a matching workspace override or resolution so the graph resolves a single Vitest version.
169
101
 
170
- A peer declaration alone does not install Vitest. If a surviving
171
- `peerDependencies.vitest` uses a catalog entry that migration will remove, it
172
- is resolved to the public peer range first.
102
+ A peer declaration alone does not install Vitest. If a surviving `peerDependencies.vitest` uses a catalog entry that migration will remove, it is resolved to the public peer range first.
173
103
 
174
104
  ### Vitest Ecosystem Packages
175
105
 
176
- Official current `@vitest/*` packages generally publish in lockstep with
177
- Vitest. Migration aligns the ones the project directly installs, including
178
- `@vitest/coverage-v8`, `@vitest/coverage-istanbul`, `@vitest/ui`, and
179
- `@vitest/web-worker`:
106
+ Official current `@vitest/*` packages generally publish in lockstep with Vitest. Migration aligns the ones the project directly installs, including `@vitest/coverage-v8`, `@vitest/coverage-istanbul`, `@vitest/ui`, and `@vitest/web-worker`:
180
107
 
181
- - when the package manager supports catalogs, they are referenced through the
182
- toolchain catalog: an existing `catalog:` / `catalog:<name>` reference is
183
- preserved, a catalog entry is added for any package that lacks one, and each
184
- entry is updated to the bundled Vitest version;
185
- - when catalogs are unsupported (npm, a standalone bun project, or a
186
- pre-catalog pnpm/Yarn), the concrete bundled version is written instead.
108
+ - when the package manager supports catalogs, they are referenced through the toolchain catalog: an existing `catalog:` / `catalog:<name>` reference is preserved, a catalog entry is added for any package that lacks one, and each entry is updated to the bundled Vitest version;
109
+ - when catalogs are unsupported (npm, a standalone bun project, or a pre-catalog pnpm/Yarn), the concrete bundled version is written instead.
187
110
 
188
111
  Packages that are **not** aligned:
189
112
 
190
113
  - `@vitest/eslint-plugin` follows its own version line;
191
- - `@vitest/coverage-c8` stopped at an older release and has no Vitest 4
192
- version; and
193
- - third-party `vitest-*` integrations keep their own compatible versions,
194
- though their required Vitest peer may still trigger
195
- [direct provisioning](#when-vitest-is-directly-required).
196
-
197
- For browser mode, the base `@vitest/browser` runtime and
198
- `@vitest/browser-preview` are bundled by Vite+ and are removed as direct
199
- dependencies. The Playwright and WebdriverIO providers stay opt-in: a kept or
200
- injected provider is referenced through the preferred toolchain catalog at the
201
- bundled Vitest version (or written concretely when catalogs are unsupported),
202
- and its `playwright` or `webdriverio` peer is installed alongside.
203
-
204
- Providers are detected before imports are rewritten. This covers legacy
205
- projects that aliased `vitest` to `@voidzero-dev/vite-plus-test` and import
206
- from `vitest/browser-<provider>`, `vitest/browser/providers/<provider>`, or
207
- `vitest/plugins/browser-<provider>`: those imports still install the
208
- corresponding `@vitest/browser-playwright` or `@vitest/browser-webdriverio`
209
- dependency and its framework peer.
210
-
211
- Object-valued nested npm and Bun overrides are preserved: they are
212
- user-defined scopes rather than scalar version pins.
114
+ - `@vitest/coverage-c8` stopped at an older release and has no Vitest 4 version; and
115
+ - third-party `vitest-*` integrations keep their own compatible versions, though their required Vitest peer may still trigger [direct provisioning](#when-vitest-is-directly-required).
116
+
117
+ For browser mode, the base `@vitest/browser` runtime and `@vitest/browser-preview` are bundled by Vite+ and are removed as direct dependencies. The Playwright and WebdriverIO providers stay opt-in: a kept or injected provider is referenced through the preferred toolchain catalog at the bundled Vitest version (or written concretely when catalogs are unsupported), and its `playwright` or `webdriverio` peer is installed alongside.
118
+
119
+ Providers are detected before imports are rewritten. This covers legacy projects that aliased `vitest` to `@voidzero-dev/vite-plus-test` and import from `vitest/browser-<provider>`, `vitest/browser/providers/<provider>`, or `vitest/plugins/browser-<provider>`: those imports still install the corresponding `@vitest/browser-playwright` or `@vitest/browser-webdriverio` dependency and its framework peer.
120
+
121
+ Object-valued nested npm and Bun overrides are preserved: they are user-defined scopes rather than scalar version pins.
213
122
 
214
123
  ## Source Rewrite Rules
215
124
 
216
125
  ### `vite` Imports
217
126
 
218
- `vite` and `vite/*` imports are rewritten to `vite-plus` **only in config
219
- entry files**: `vite.config.*`, `vitest.config.*`, and any config file the
220
- migration resolved. Every other file keeps its `vite` imports, for two
221
- reasons:
222
-
223
- - `vite-plus` is not a guaranteed superset of Vite's exposed surface. It owns
224
- only `defineConfig`, `defineProject`, and `lazyPlugins`, so rewriting a
225
- pass-through symbol such as `createBuilder` or `loadConfigFromFile`
226
- (including in `typeof import('vite')` type positions) can break.
227
- - An unrewritten `vite` import still resolves through the
228
- `@voidzero-dev/vite-plus-core` alias in a Vite+ project.
229
-
230
- Plugin packages (an unscoped name starting with `vite-plugin-` or
231
- `unplugin-`, or `vite` in `peerDependencies`/`dependencies`) skip the rewrite
232
- even in config files. Only the `vite` specifier is in scope for this rule.
233
-
234
- `declare module 'vite'` augmentations follow the same rule and are preserved
235
- outside config files. Through the core alias they reach the same
236
- `@voidzero-dev/vite-plus-core` module whose `UserConfig` types `defineConfig`
237
- from `vite-plus`, so they keep working after migration; `vite-plus` itself
238
- exports no `UserConfig` symbol, so a rewritten `declare module 'vite-plus'`
239
- augmentation would merge with nothing. Extensions aimed at `vite-plus`'s own
240
- surface are written against `vite-plus` by hand.
127
+ `vite` and `vite/*` imports are rewritten to `vite-plus` **only in config entry files**: `vite.config.*`, `vitest.config.*`, and any config file the migration resolved. Every other file keeps its `vite` imports, for two reasons:
128
+
129
+ - `vite-plus` is not a guaranteed superset of Vite's exposed surface. It owns only `defineConfig`, `defineProject`, and `lazyPlugins`, so rewriting a pass-through symbol such as `createBuilder` or `loadConfigFromFile` (including in `typeof import('vite')` type positions) can break.
130
+ - An unrewritten `vite` import still resolves through the `@voidzero-dev/vite-plus-core` alias in a Vite+ project.
131
+
132
+ Plugin packages (an unscoped name starting with `vite-plugin-` or `unplugin-`, or `vite` in `peerDependencies`/`dependencies`) skip the rewrite even in config files. Only the `vite` specifier is in scope for this rule.
133
+
134
+ `declare module 'vite'` augmentations follow the same rule and are preserved outside config files. Through the core alias they reach the same `@voidzero-dev/vite-plus-core` module whose `UserConfig` types `defineConfig` from `vite-plus`, so they keep working after migration; `vite-plus` itself exports no `UserConfig` symbol, so a rewritten `declare module 'vite-plus'` augmentation would merge with nothing. Extensions aimed at `vite-plus`'s own surface are written against `vite-plus` by hand.
241
135
 
242
136
  ### `vitest` and Browser Imports
243
137
 
244
- - Ordinary `vitest` and `vitest/*` imports are rewritten to
245
- `vite-plus/test*`.
246
- - Legacy Playwright and WebdriverIO provider imports are detected before this
247
- rewrite so their optional provider dependencies are not lost.
248
- - Scoped `@vitest/browser*` imports are rewritten to the corresponding
249
- `vite-plus/test/browser*` exports, provisioning opt-in providers when
250
- needed.
138
+ - Ordinary `vitest` and `vitest/*` imports are rewritten to `vite-plus/test*`.
139
+ - Legacy Playwright and WebdriverIO provider imports are detected before this rewrite so their optional provider dependencies are not lost.
140
+ - Scoped `@vitest/browser*` imports are rewritten to the corresponding `vite-plus/test/browser*` exports, provisioning opt-in providers when needed.
251
141
  - Existing `vite-plus/test*` imports are left unchanged.
252
142
 
253
143
  ### Oxlint JS Plugin Imports
254
144
 
255
- Vite+ bundles Oxlint, so the migration removes a standalone `oxlint`
256
- dependency. Your own Oxlint JS plugins import the authoring API by name. That
257
- import stops resolving when the dependency goes away. `vp lint` then fails to
258
- load the plugin.
145
+ Vite+ bundles Oxlint, so the migration removes a standalone `oxlint` dependency. Your own Oxlint JS plugins import the authoring API by name. That import stops resolving when the dependency goes away. `vp lint` then fails to load the plugin.
259
146
 
260
147
  The migration repoints those imports at Vite+:
261
148
 
262
149
  - It rewrites `@oxlint/plugins` to `vite-plus/lint/plugins`.
263
150
  - It rewrites `oxlint/plugins-dev` to `vite-plus/lint/plugins-dev`.
264
- - It rewrites `oxlint` to `vite-plus/lint/plugins` when the import names a
265
- binding from the authoring API, such as `defineRule`, `definePlugin`, or
266
- `Context`. Older Oxlint releases exposed that API from the main entry. It now
267
- lives in `@oxlint/plugins`.
151
+ - It rewrites `oxlint` to `vite-plus/lint/plugins` when the import names a binding from the authoring API, such as `defineRule`, `definePlugin`, or `Context`. Older Oxlint releases exposed that API from the main entry. It now lives in `@oxlint/plugins`.
268
152
 
269
- An import through Vite+ always matches the version of Oxlint that Vite+
270
- bundles. You pin no second package. The import also resolves from any package
271
- that already depends on `vite-plus`.
153
+ An import through Vite+ always matches the version of Oxlint that Vite+ bundles. You pin no second package. The import also resolves from any package that already depends on `vite-plus`.
272
154
 
273
155
  The migration leaves three forms alone:
274
156
 
275
- - `oxlint` imports that name only the config surface, such as `defineConfig`,
276
- `OxlintConfig`, or `OxlintOverride`. These still resolve against the
277
- standalone package.
278
- - Default and namespace `oxlint` imports. They name no binding, so the
279
- migration cannot tell the two surfaces apart.
157
+ - `oxlint` imports that name only the config surface, such as `defineConfig`, `OxlintConfig`, or `OxlintOverride`. These still resolve against the standalone package.
158
+ - Default and namespace `oxlint` imports. They name no binding, so the migration cannot tell the two surfaces apart.
280
159
  - Bare side-effect `oxlint` imports, for the same reason.
281
160
 
282
- The migration also skips a package that declares `oxlint` or `@oxlint/plugins`
283
- in `dependencies` or `peerDependencies`, or `@oxlint/plugins` in
284
- `optionalDependencies`. These dependencies can supply a published Oxlint plugin.
285
- Its consumers may not run Vite+.
161
+ The migration also skips a package that declares `oxlint` or `@oxlint/plugins` in `dependencies` or `peerDependencies`, or `@oxlint/plugins` in `optionalDependencies`. These dependencies can supply a published Oxlint plugin. Its consumers may not run Vite+.
286
162
 
287
- The cleanup retains a development dependency on `@oxlint/plugins` when source,
288
- package import aliases, or built plugins still reference it. This includes
289
- ignored output in directories such as `dist`, `build`, and `out`.
163
+ The cleanup retains a development dependency on `@oxlint/plugins` when source, package import aliases, or built plugins still reference it. This includes ignored output in directories such as `dist`, `build`, and `out`.
290
164
 
291
165
  ### What Is Never Rewritten
292
166
 
293
- - `declare module 'vitest'` and `declare module '@vitest/browser*'`: module
294
- augmentation must retain the upstream module identity.
295
- - References that stay behind, such as `compilerOptions.types`,
296
- `require.resolve`, `import.meta.resolve`, and `vitest/package.json`,
297
- require package-local Vitest (see
298
- [When Vitest Is Directly Required](#when-vitest-is-directly-required)).
299
- - In a package that declares `@nuxt/test-utils`, every `vitest` and
300
- `vitest/*` module specifier is preserved package-wide: the Nuxt transform
301
- requires the upstream identity and can otherwise inject a duplicate `vi`
302
- import. This exception does not apply to sibling packages or to scoped
303
- `@vitest/browser*` imports.
304
-
305
- The `prefer-vite-plus-imports` lint rule follows the same Nuxt exception, so
306
- lint autofix preserves these imports too.
167
+ - `declare module 'vitest'` and `declare module '@vitest/browser*'`: module augmentation must retain the upstream module identity.
168
+ - References that stay behind, such as `compilerOptions.types`, `require.resolve`, `import.meta.resolve`, and `vitest/package.json`, require package-local Vitest (see [When Vitest Is Directly Required](#when-vitest-is-directly-required)).
169
+ - In a package that declares `@nuxt/test-utils`, every `vitest` and `vitest/*` module specifier is preserved package-wide: the Nuxt transform requires the upstream identity and can otherwise inject a duplicate `vi` import. This exception does not apply to sibling packages or to scoped `@vitest/browser*` imports.
170
+
171
+ The `prefer-vite-plus-imports` lint rule follows the same Nuxt exception, so lint autofix preserves these imports too.
307
172
 
308
173
  ## Package Script Rewrite Rules
309
174
 
310
- Migration rewrites commands provided by the Vite+ toolchain in `package.json`
311
- scripts while preserving their arguments:
175
+ Migration rewrites commands provided by the Vite+ toolchain in `package.json` scripts while preserving their arguments:
312
176
 
313
177
  | Before | After |
314
178
  | ------------- | ------------------------------------------- |
@@ -322,10 +186,7 @@ scripts while preserving their arguments:
322
186
  | `prettier` | `vp fmt`, when its optional migration runs |
323
187
  | `tsup` | `vp pack`, when its optional migration runs |
324
188
 
325
- For commands launched through `bunx`, migration preserves `bunx` and its
326
- `--bun` flag (keeping the user's chosen runtime) and rewrites only the managed
327
- command. This also works when `bunx` follows a command-launcher delimiter such
328
- as `run` or `--`:
189
+ For commands launched through `bunx`, migration preserves `bunx` and its `--bun` flag (keeping the user's chosen runtime) and rewrites only the managed command. This also works when `bunx` follows a command-launcher delimiter such as `run` or `--`:
329
190
 
330
191
  | Before | After |
331
192
  | ------------------------------------------------------- | -------------------------------------------------------- |
@@ -338,112 +199,54 @@ Unrelated `bunx` commands and other package-executor forms remain unchanged.
338
199
 
339
200
  ## Continuous Integration Rules
340
201
 
341
- Migration replaces exact `voidzero-dev/setup-vp@v1` references in GitHub
342
- Actions workflows and composite actions under `.github` with the latest exact
343
- `setup-vp` release known to that Vite+ version. The frozen `v1` tag does not
344
- receive new releases. Existing exact versions and commit SHAs are left
345
- unchanged.
202
+ Migration replaces exact `voidzero-dev/setup-vp@v1` references in GitHub Actions workflows and composite actions under `.github` with the latest exact `setup-vp` release known to that Vite+ version. The frozen `v1` tag does not receive new releases. Existing exact versions and commit SHAs are left unchanged.
346
203
 
347
204
  ## Node.js Version Rules
348
205
 
349
- Migration converts legacy Node.js version-manager files to `.node-version`,
350
- the format Vite+ reads. On an existing Vite+ project this conversion is part
351
- of the full setup bucket, so it runs with `vp migrate --full`; fresh
352
- migrations run it unconditionally.
206
+ Migration converts legacy Node.js version-manager files to `.node-version`, the format Vite+ reads. On an existing Vite+ project this conversion is part of the full setup bucket, so it runs with `vp migrate --full`; fresh migrations run it unconditionally.
353
207
 
354
- - `.nvmrc` and Volta `volta.node` pins are converted to `.node-version`. An
355
- existing `.node-version` is kept.
356
- - When `.nvmrc` is removed, any `actions/setup-node` `node-version-file:
357
- .nvmrc` reference in `.github/workflows/*.{yml,yaml}` and composite actions
358
- under `.github` (`.github/**/action.{yml,yaml}`) is repointed to
359
- `.node-version` so CI does not fail with "node version file ... does not
360
- exist".
208
+ - `.nvmrc` and Volta `volta.node` pins are converted to `.node-version`. An existing `.node-version` is kept.
209
+ - When `.nvmrc` is removed, any `actions/setup-node` `node-version-file: .nvmrc` reference in `.github/workflows/*.{yml,yaml}` and composite actions under `.github` (`.github/**/action.{yml,yaml}`) is repointed to `.node-version` so CI does not fail with "node version file ... does not exist".
361
210
 
362
211
  ## Package-Manager Rules
363
212
 
364
213
  ### pnpm
365
214
 
366
- **Root settings location.** pnpm 10.6.2+ uses `pnpm-workspace.yaml` as the
367
- single source for supported root settings. Migration moves recognized
368
- `package.json#pnpm` fields there, including overrides, peer rules, patch
369
- settings, package extensions, architecture and build policy, audit/update
370
- configuration, and configuration dependencies. It removes the `pnpm` object
371
- when it becomes empty and preserves unknown keys that may belong to other
372
- tooling.
373
-
374
- - When both files define the same migrated setting, object entries are merged
375
- recursively and unique array entries are retained. Values from
376
- `package.json#pnpm` win at conflicting scalar leaves, while workspace-only
377
- sibling entries are preserved.
378
- - Before pnpm 10.6.2, these settings stay in `package.json#pnpm`. (Workspace
379
- settings support arrived incrementally: 10.5.0 in general, 10.5.1 for
380
- overrides, 10.6.2 for `peerDependencyRules`. pnpm 11 no longer reads the
381
- legacy `package.json` settings.)
382
-
383
- **Catalogs.** Catalogs are a separate feature, supported from pnpm 9.5.0,
384
- independent of the settings boundary above. Even below 10.6.2, where
385
- overrides stay in `package.json#pnpm`, migration still rewrites the workspace
386
- catalog off stale wrapper aliases and keeps `catalog:` overrides as
387
- references rather than inlining them to concrete versions.
388
-
389
- - Dependency references, default and named catalogs, overrides, and
390
- `peerDependencyRules` are kept consistent with each other.
391
- - pnpm accepts the logical default catalog as either top-level `catalog` or
392
- `catalogs.default`, but not both. Migration preserves the existing form and
393
- never creates the other form beside it.
394
- - When an existing named catalog already owns `vite-plus`, `vite`, or
395
- `vitest`, migration reuses that managed toolchain catalog for newly added
396
- dependencies and overrides. It creates a top-level default catalog only
397
- when no managed or default catalog can be reused.
215
+ **Root settings location.** pnpm 10.6.2+ uses `pnpm-workspace.yaml` as the single source for supported root settings. Migration moves recognized `package.json#pnpm` fields there, including overrides, peer rules, patch settings, package extensions, architecture and build policy, audit/update configuration, and configuration dependencies. It removes the `pnpm` object when it becomes empty and preserves unknown keys that may belong to other tooling.
216
+
217
+ - When both files define the same migrated setting, object entries are merged recursively and unique array entries are retained. Values from `package.json#pnpm` win at conflicting scalar leaves, while workspace-only sibling entries are preserved.
218
+ - Before pnpm 10.6.2, these settings stay in `package.json#pnpm`. (Workspace settings support arrived incrementally: 10.5.0 in general, 10.5.1 for overrides, 10.6.2 for `peerDependencyRules`. pnpm 11 no longer reads the legacy `package.json` settings.)
219
+
220
+ **Catalogs.** Catalogs are a separate feature, supported from pnpm 9.5.0, independent of the settings boundary above. Even below 10.6.2, where overrides stay in `package.json#pnpm`, migration still rewrites the workspace catalog off stale wrapper aliases and keeps `catalog:` overrides as references rather than inlining them to concrete versions.
221
+
222
+ - Dependency references, default and named catalogs, overrides, and `peerDependencyRules` are kept consistent with each other.
223
+ - pnpm accepts the logical default catalog as either top-level `catalog` or `catalogs.default`, but not both. Migration preserves the existing form and never creates the other form beside it.
224
+ - When an existing named catalog already owns `vite-plus`, `vite`, or `vitest`, migration reuses that managed toolchain catalog for newly added dependencies and overrides. It creates a top-level default catalog only when no managed or default catalog can be reused.
398
225
 
399
226
  **Other rules.**
400
227
 
401
- - Each package that declares `vite-plus` also gets a direct `vite` dev
402
- dependency (see [Vite and Overrides](#vite-and-overrides)).
228
+ - Each package that declares `vite-plus` also gets a direct `vite` dev dependency (see [Vite and Overrides](#vite-and-overrides)).
403
229
  - Unrelated selector-shaped and object-valued overrides are preserved.
404
230
 
405
231
  ### npm
406
232
 
407
- - Direct aliases are normalized before the matching override is added, so npm
408
- does not fail with `EOVERRIDE`.
409
- - When a real Vite installation changes to the core alias, stale Vite install
410
- and lockfile state is removed before reinstalling.
411
- - Opt-in browser-provider layouts get a top-level `vite` edge when nested
412
- Vitest packages otherwise cannot resolve it.
233
+ - Direct aliases are normalized before the matching override is added, so npm does not fail with `EOVERRIDE`.
234
+ - When a real Vite installation changes to the core alias, stale Vite install and lockfile state is removed before reinstalling.
235
+ - Opt-in browser-provider layouts get a top-level `vite` edge when nested Vitest packages otherwise cannot resolve it.
413
236
 
414
237
  ### Yarn
415
238
 
416
- - Vite+ does not support Plug'n'Play. Migration detects explicit and implicit
417
- PnP and converts the project to `nodeLinker: node-modules`, preserving all
418
- unrelated `.yarnrc.yml` settings. `--no-interactive` accepts the
419
- conversion; a process-level `YARN_NODE_LINKER=pnp` must be fixed by the
420
- caller.
239
+ - Vite+ does not support Plug'n'Play. Migration detects explicit and implicit PnP and converts the project to `nodeLinker: node-modules`, preserving all unrelated `.yarnrc.yml` settings. `--no-interactive` accepts the conversion; a process-level `YARN_NODE_LINKER=pnp` must be fixed by the caller.
421
240
  - Catalog references and user hoisting settings are preserved.
422
- - Migration avoids split Vitest copies under workspace hoisting isolation: it
423
- applies a package-level fix where possible and warns when the isolation
424
- cannot be changed safely.
241
+ - Migration avoids split Vitest copies under workspace hoisting isolation: it applies a package-level fix where possible and warns when the isolation cannot be changed safely.
425
242
 
426
243
  ### Bun
427
244
 
428
- - Bun catalogs only resolve inside a workspace (a root `package.json` with a
429
- non-empty `workspaces`). In a bun workspace, existing top-level or
430
- workspace catalog locations and named catalog references are preserved. A
431
- standalone (single-package) bun project keeps concrete specs and gets no
432
- catalog field, because `bun install` cannot resolve `catalog:` outside a
433
- workspace.
434
- - The core alias is mirrored as a direct `vite` dependency so Bun sees the
435
- peer provider before applying overrides.
245
+ - Bun catalogs only resolve inside a workspace (a root `package.json` with a non-empty `workspaces`). In a bun workspace, existing top-level or workspace catalog locations and named catalog references are preserved. A standalone (single-package) bun project keeps concrete specs and gets no catalog field, because `bun install` cannot resolve `catalog:` outside a workspace.
246
+ - The core alias is mirrored as a direct `vite` dependency so Bun sees the peer provider before applying overrides.
436
247
 
437
248
  ## After the Migration
438
249
 
439
- - Each Vite config is inspected for Rolldown-incompatible patterns (such as
440
- `manualChunks`). Anything found is reported as a warning; the config is not
441
- changed.
442
- - Dependencies are reinstalled once to refresh the lockfile. If installation
443
- fails, migration reports the error and exits with a nonzero status.
444
- - After a successful migration, `vp fmt` runs on the files changed during
445
- migration, excluding paths that were already dirty in the Git worktree.
446
- Oxfmt selects the supported formats; non-Git projects retain full-project
447
- formatting. Formatting is skipped while the project still uses Prettier. A
448
- formatter failure is reported as a warning so the migration result and the
449
- manual formatting command remain available.
250
+ - Each Vite config is inspected for Rolldown-incompatible patterns (such as `manualChunks`). Anything found is reported as a warning; the config is not changed.
251
+ - Dependencies are reinstalled once to refresh the lockfile. If installation fails, migration reports the error and exits with a nonzero status.
252
+ - After a successful migration, `vp fmt` runs on the files changed during migration, excluding paths that were already dirty in the Git worktree. Oxfmt selects the supported formats; non-Git projects retain full-project formatting. Formatting is skipped while the project still uses Prettier. A formatter failure is reported as a warning so the migration result and the manual formatting command remain available.
@@ -22,9 +22,7 @@ The positional `PATH` argument is optional.
22
22
 
23
23
  - If omitted, `vp migrate` migrates the current directory
24
24
  - If provided, it migrates that target directory instead
25
- - For a monorepo, the target must be the workspace root. Vite+ cannot
26
- migrate one workspace member, because migration updates the package-manager
27
- configuration, the catalogs, and the lockfiles that all members share.
25
+ - For a monorepo, the target must be the workspace root. Vite+ cannot migrate one workspace member, because migration updates the package-manager configuration, the catalogs, and the lockfiles that all members share.
28
26
 
29
27
  ```bash
30
28
  vp migrate
@@ -53,8 +51,7 @@ The `migrate` command is designed to move existing projects onto Vite+ quickly.
53
51
  - Can write agent and editor configuration files
54
52
  - Formats the migrated project
55
53
 
56
- See [Migration Rules](./migrate-rules.md) for the exact dependency, source
57
- rewrite, and package-manager behavior.
54
+ See [Migration Rules](./migrate-rules.md) for the exact dependency, source rewrite, and package-manager behavior.
58
55
 
59
56
  Most projects will require further manual adjustments after running `vp migrate`.
60
57
 
@@ -72,40 +69,6 @@ After running the migration:
72
69
  - Run `vp test`
73
70
  - Run `vp build` (or `vp pack` if you are building a library)
74
71
 
75
- ## Manual Installation & Migration
76
-
77
- If you are manually migrating a project to Vite+, install these dev dependencies first:
78
-
79
- ```bash
80
- vp install -D vite-plus
81
- ```
82
-
83
- You need to add overrides to your package manager so that other packages resolve the Vite+ versions: alias `vite` to `@voidzero-dev/vite-plus-core`, and pin `vitest` to the version Vite+ bundles (run `vp --version`) so the whole project shares a single Vitest copy with `vp test`. Without the `vitest` pin, a dependency or workspace package can pull a different Vitest than the bundled runner, splitting Vitest's internals (mocks, `expect`, runner state):
84
-
85
- ```json
86
- "overrides": {
87
- "vite": "npm:@voidzero-dev/vite-plus-core@latest",
88
- "vitest": "4.1.11"
89
- }
90
- ```
91
-
92
- If you are using `pnpm`, add this to your `pnpm-workspace.yaml`:
93
-
94
- ```yaml
95
- overrides:
96
- vite: npm:@voidzero-dev/vite-plus-core@latest
97
- vitest: 4.1.11
98
- ```
99
-
100
- Or, if you are using Yarn:
101
-
102
- ```json
103
- "resolutions": {
104
- "vite": "npm:@voidzero-dev/vite-plus-core@latest",
105
- "vitest": "4.1.11"
106
- }
107
- ```
108
-
109
72
  ## Migration Prompt
110
73
 
111
74
  If you want to hand this work to a coding agent (or the reader is a coding agent!), use this migration prompt:
@@ -205,19 +168,13 @@ export default defineConfig({
205
168
  });
206
169
  ```
207
170
 
208
- When no existing hook policy owns the workflow, `vp migrate` can move supported lint-staged rules
209
- and remove the old configuration and dependency. If an existing hook tool is preserved, keep
210
- lint-staged in place until you convert that hook policy manually. See the
211
- [Commit hooks guide](/guide/commit-hooks) and [Staged config reference](/config/staged) for details.
171
+ When no existing hook policy owns the workflow, `vp migrate` can move supported lint-staged rules and remove the old configuration and dependency. If an existing hook tool is preserved, keep lint-staged in place until you convert that hook policy manually. See the [Commit hooks guide](/guide/commit-hooks) and [Staged config reference](/config/staged) for details.
212
172
 
213
173
  ### Git hook tools
214
174
 
215
- The `vp migrate` command does not automatically convert Husky setups. When Husky is detected,
216
- Vite+ leaves its hooks, lifecycle scripts, configuration, and dependencies unchanged and shows a
217
- warning. You can migrate the project manually using the [Commit hooks guide](/guide/commit-hooks).
175
+ The `vp migrate` command does not automatically convert Husky setups. When Husky is detected, Vite+ leaves its hooks, lifecycle scripts, configuration, and dependencies unchanged and shows a warning. You can migrate the project manually using the [Commit hooks guide](/guide/commit-hooks).
218
176
 
219
- Existing project-owned Vite+ hooks are also preserved. The default staged workflow is introduced
220
- only when no existing hook policy is found.
177
+ Existing project-owned Vite+ hooks are also preserved. The default staged workflow is introduced only when no existing hook policy is found.
221
178
 
222
179
  If your project currently uses `lefthook`, `simple-git-hooks`, or `yorkie`, `vp migrate` will leave your existing configuration alone and show a warning. This happens even if you choose to set up hooks during the prompt or include the `--hooks` flag.
223
180
 
package/docs/guide/run.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Run
2
2
 
3
- `vp run` runs `package.json` scripts and tasks defined in `vite.config.ts`. It works like `pnpm run`, with caching, dependency ordering, and workspace-aware execution built in.
3
+ `vp run` runs `package.json` scripts and tasks defined in `vite.config.ts`. It works like `pnpm run`, with caching, dependency ordering, and workspace-aware execution built in. The task runner is available from both the [global CLI](/guide/global-cli) and the [project-local CLI](/guide/local-cli).
4
4
 
5
5
  ::: tip
6
6
  `vpr` is available as a standalone shorthand for `vp run`. All examples below work with both `vp run` and `vpr`.