@nx/vite 23.0.0-beta.21 → 23.0.0-beta.23
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.
- package/dist/plugins/nx-copy-assets.plugin.d.ts +6 -0
- package/dist/plugins/nx-copy-assets.plugin.js +8 -0
- package/dist/plugins/nx-tsconfig-paths.plugin.d.ts +7 -0
- package/dist/plugins/nx-tsconfig-paths.plugin.js +9 -0
- package/dist/src/generators/configuration/configuration.js +2 -0
- package/dist/src/generators/convert-to-inferred/convert-to-inferred.js +2 -0
- package/dist/src/generators/init/init.js +2 -0
- package/dist/src/generators/init/lib/utils.js +1 -1
- package/dist/src/generators/init/schema.json +1 -1
- package/dist/src/generators/setup-paths-plugin/setup-paths-plugin.js +2 -0
- package/dist/src/migrations/update-23-0-0/ai-instructions-for-vitest-3.md +604 -0
- package/dist/src/migrations/update-23-0-0/ai-instructions-for-vitest-4.md +817 -0
- package/dist/src/migrations/update-23-0-0/lib/ast-edits.d.ts +26 -0
- package/dist/src/migrations/update-23-0-0/lib/ast-edits.js +49 -0
- package/dist/src/migrations/update-23-0-0/lib/ci-files.d.ts +3 -0
- package/dist/src/migrations/update-23-0-0/lib/ci-files.js +30 -0
- package/dist/src/migrations/update-23-0-0/lib/vitest-config-files.d.ts +5 -0
- package/dist/src/migrations/update-23-0-0/lib/vitest-config-files.js +34 -0
- package/dist/src/migrations/update-23-0-0/migrate-to-vitest-3.d.ts +10 -0
- package/dist/src/migrations/update-23-0-0/migrate-to-vitest-3.js +335 -0
- package/dist/src/migrations/update-23-0-0/migrate-to-vitest-4.d.ts +17 -0
- package/dist/src/migrations/update-23-0-0/migrate-to-vitest-4.js +726 -0
- package/dist/src/plugins/plugin.d.ts +3 -3
- package/dist/src/utils/assert-supported-vite-version.d.ts +2 -0
- package/dist/src/utils/assert-supported-vite-version.js +8 -0
- package/dist/src/utils/deprecation.d.ts +4 -0
- package/dist/src/utils/deprecation.js +26 -1
- package/dist/src/utils/ensure-dependencies.js +1 -1
- package/dist/src/utils/generator-utils.js +2 -0
- package/dist/src/utils/versions.d.ts +1 -0
- package/dist/src/utils/versions.js +7 -1
- package/migrations.json +116 -9
- package/package.json +6 -6
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
# Vitest 4.0 Migration Instructions for LLM
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
These instructions guide you through migrating an Nx workspace containing multiple Vitest projects from Vitest 3.x to Vitest 4.0. Work systematically through each breaking change category.
|
|
6
|
+
|
|
7
|
+
<pre_pass_summary note="a deterministic pre-pass already applied these specific edits; verify the new shape is in place rather than redoing them">
|
|
8
|
+
|
|
9
|
+
The pre-pass handled, mechanically:
|
|
10
|
+
|
|
11
|
+
- dead `coverage.{all,extensions,ignoreEmptyLines,experimentalAstAwareRemapping}` removal
|
|
12
|
+
- `test.workspace` → `test.projects` rename (the property only — external `vitest.workspace.*` files are NOT inlined)
|
|
13
|
+
- `@vitest/browser/context` import-path rewrite to `vitest/browser`
|
|
14
|
+
- `deps.optimizer.web` → `deps.optimizer.client` rename
|
|
15
|
+
- `poolOptions.threads.useAtomics` and top-level `test.minWorkers` removal
|
|
16
|
+
- `'verbose'` → `'tree'` and `'basic'` → `['default', { summary: false }]` inside `test.reporters`
|
|
17
|
+
- `VITEST_MAX_{THREADS,FORKS}` → `VITEST_MAX_WORKERS` and `VITE_NODE_DEPS_MODULE_DIRECTORIES` → `VITEST_MODULE_DIRECTORIES` renames in: `package.json` scripts, `.env` / `.env.*` files, `project.json` `options.env` keys, and inline `VAR=value` prefixes inside `project.json` `options.{args,command,commands}`
|
|
18
|
+
|
|
19
|
+
The pre-pass **skips the rename when both `VITEST_MAX_THREADS` and `VITEST_MAX_FORKS` appear in the same file/scope** (they collapse to a single `VITEST_MAX_WORKERS` whose value depends on which pool the project uses — a decision the pre-pass can't make safely). It also **does not** edit CI provider configs (`.github/workflows/*.yml`, `.gitlab-ci.yml`, `azure-pipelines.yml`, `.circleci/config.yml`, `bitbucket-pipelines.yml`) — YAML structure varies too much. Any conflicts and any CI matches are forwarded to you in `<advisory_context>`.
|
|
20
|
+
|
|
21
|
+
**The cross-cutting changes below still require your attention** — pool option flattening (`singleThread`/`singleFork`, `maxThreads`/`maxForks`, `poolOptions.<pool>.{execArgv,isolate}`, `poolOptions.vmThreads.memoryLimit`), `test.deps.{external,inline,fallbackCJS}` → `test.server.deps.*` move, `test.{poolMatchGlobs,environmentMatchGlobs}` projects rewrite, browser provider function-form rewrite, `browser.testerScripts` → `testerHtmlPath`, `vitest.workspace.*` file inlining + `defineWorkspace` removal, custom reporter callback API updates, and `@vitest/browser` package replacement with per-provider packages.
|
|
22
|
+
|
|
23
|
+
How to read the wrapper sections above this file:
|
|
24
|
+
|
|
25
|
+
- `<files_changed>` lists files the pre-pass already wrote to. Verify the new shape is in place; do not re-apply the same edit.
|
|
26
|
+
- `<advisory_context>` lists detections the pre-pass forwarded because it could not safely complete them. **Every entry is pending work** — address each one in the relevant section below, not as a separate task.
|
|
27
|
+
|
|
28
|
+
A workspace-wide reminder is also emitted as a post-run "next step" about env vars set in CI provider dashboards — those can't be detected from the workspace tree.
|
|
29
|
+
|
|
30
|
+
</pre_pass_summary>
|
|
31
|
+
|
|
32
|
+
<handoff_guidance>
|
|
33
|
+
In your handoff `summary` (1–3 sentences per the system prompt), name the breaking-change categories you applied; explicitly call out any you skipped because they didn't apply (e.g., "no custom reporters in this workspace", "no browser-mode configs").
|
|
34
|
+
</handoff_guidance>
|
|
35
|
+
|
|
36
|
+
<prerequisites note="hard runtime requirements; do not edit any vitest config until these are satisfied">
|
|
37
|
+
|
|
38
|
+
Vitest 4 has hard runtime requirements:
|
|
39
|
+
|
|
40
|
+
- **Vite ≥ 6.0.0** (Vite 5 is unsupported). Check with `npx vite --version`. If on Vite 5, apply the Vite 6 / 7 / 8 migration guides first.
|
|
41
|
+
- **Node.js ≥ 20.0.0** (Node 18 support dropped). Check with `node --version`. Update CI `actions/setup-node` versions, `.nvmrc`, `engines` in `package.json`, and Docker base images.
|
|
42
|
+
|
|
43
|
+
If either prerequisite is unmet, write status: failed with the unmet requirement in `summary` — config-level migration on an unsupported runtime will produce confusing errors.
|
|
44
|
+
|
|
45
|
+
</prerequisites>
|
|
46
|
+
|
|
47
|
+
## Nx-Specific Notes (read first)
|
|
48
|
+
|
|
49
|
+
- **Inferred plugin targets**: modern Nx workspaces use `@nx/vitest/plugin` (or historically `@nx/vite/plugin`) to _infer_ test targets from `vitest.config.*` presence. `project.json` may have no `test` target. Inspect inferred targets with `nx show project <name> --json | jq .targets`. Renaming/moving `vitest.config.*` invalidates inference; run `nx reset` after structural moves.
|
|
50
|
+
- **`@nx/vitest:test` / `@nx/vite:test` executor options**: when present in `project.json`, the relevant options are `configFile`, `reportsDirectory`, `mode`, `testFiles`, `watch`. Most option-level breaking changes in v4 are inside `vitest.config.*`, not these. The exception: any `--segfault-retry` in the executor `args` is now invalid and must be removed.
|
|
51
|
+
- **Shared base config**: apply transforms to a workspace-root `vitest.config.base.ts` (extended via `mergeConfig`) BEFORE per-project overrides. Otherwise inherited options may shadow the migrated ones.
|
|
52
|
+
- **Angular projects using AnalogJS** (`@analogjs/vitest-angular` / `@analogjs/vite-plugin-angular`): the Analog packages are bumped automatically by Nx's `packageJsonUpdates` (to the `~2.2.x` line). Review `src/test-setup.ts` and Analog plugin invocations in per-project `vitest.config.ts`.
|
|
53
|
+
|
|
54
|
+
## Pre-Migration Checklist
|
|
55
|
+
|
|
56
|
+
1. **Identify all Vitest projects**:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
nx show projects --with-target test
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. **Locate all Vitest configuration files**:
|
|
63
|
+
- Search for `vitest.config.{ts,js,mjs}`
|
|
64
|
+
- Search for `vitest.workspace.{ts,js,mjs}` (removed in Vitest 4 — migrate to inline `test.projects`; see section 1.3 below)
|
|
65
|
+
- Check `project.json` files for `@nx/vitest:test` / `@nx/vite:test` executor options
|
|
66
|
+
- For workspaces relying on the inferred plugin (`@nx/vitest/plugin`), targets come from inference — inspect them with `nx show project <name> --json | jq .targets`
|
|
67
|
+
|
|
68
|
+
3. **Identify affected code**:
|
|
69
|
+
- Test files: `**/*.{spec,test}.{ts,js,tsx,jsx}`
|
|
70
|
+
- Mock usage: Files using `vi.fn()`, `vi.spyOn()`, `vi.mock()`
|
|
71
|
+
- Coverage configuration references
|
|
72
|
+
|
|
73
|
+
## Migration Steps by Category
|
|
74
|
+
|
|
75
|
+
### 1. Configuration File Updates
|
|
76
|
+
|
|
77
|
+
#### 1.1 Coverage Configuration
|
|
78
|
+
|
|
79
|
+
**Search Pattern**: `coverage` in all `vitest.config.*` files and `project.json` test target options
|
|
80
|
+
|
|
81
|
+
**Changes Required**:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
85
|
+
export default defineConfig({
|
|
86
|
+
test: {
|
|
87
|
+
coverage: {
|
|
88
|
+
all: true,
|
|
89
|
+
extensions: ['.ts', '.tsx'],
|
|
90
|
+
ignoreEmptyLines: false,
|
|
91
|
+
experimentalAstAwareRemapping: true,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ✅ AFTER (Vitest 4.0)
|
|
97
|
+
export default defineConfig({
|
|
98
|
+
test: {
|
|
99
|
+
coverage: {
|
|
100
|
+
// Explicitly define files to include in coverage
|
|
101
|
+
include: ['src/**/*.{ts,tsx}'],
|
|
102
|
+
// Remove: all, extensions, ignoreEmptyLines, experimentalAstAwareRemapping
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Action Items**:
|
|
109
|
+
|
|
110
|
+
- [ ] Remove `coverage.all` option
|
|
111
|
+
- [ ] Remove `coverage.extensions` option
|
|
112
|
+
- [ ] Remove `coverage.ignoreEmptyLines` option
|
|
113
|
+
- [ ] Remove `coverage.experimentalAstAwareRemapping` option
|
|
114
|
+
- [ ] Add explicit `coverage.include` patterns based on project structure
|
|
115
|
+
- [ ] Update any documentation referencing these options
|
|
116
|
+
|
|
117
|
+
#### 1.2 Pool Options Restructuring
|
|
118
|
+
|
|
119
|
+
**Search Pattern**: `poolOptions`, `maxThreads`, `maxForks`, `singleThread`, `singleFork` in all Vitest config files
|
|
120
|
+
|
|
121
|
+
**Changes Required**:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// ❌ BEFORE (Vitest 3.x — pool serialized via singleThread/singleFork)
|
|
125
|
+
export default defineConfig({
|
|
126
|
+
test: {
|
|
127
|
+
maxThreads: 4,
|
|
128
|
+
maxForks: 2,
|
|
129
|
+
singleFork: true,
|
|
130
|
+
poolOptions: {
|
|
131
|
+
forks: {
|
|
132
|
+
execArgv: ['--expose-gc'],
|
|
133
|
+
isolate: false,
|
|
134
|
+
},
|
|
135
|
+
threads: {
|
|
136
|
+
useAtomics: true,
|
|
137
|
+
},
|
|
138
|
+
vmThreads: {
|
|
139
|
+
memoryLimit: '512MB',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// ✅ AFTER (Vitest 4.0 — top-level pool config)
|
|
146
|
+
export default defineConfig({
|
|
147
|
+
test: {
|
|
148
|
+
maxWorkers: 1, // singleFork: true => maxWorkers: 1, isolate: false
|
|
149
|
+
isolate: false,
|
|
150
|
+
execArgv: ['--expose-gc'], // moved from poolOptions.forks
|
|
151
|
+
vmMemoryLimit: '512MB', // moved from poolOptions.vmThreads.memoryLimit
|
|
152
|
+
// Remove: poolOptions, threads.useAtomics, minWorkers (also removed in v4)
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Action Items**:
|
|
158
|
+
|
|
159
|
+
- [ ] Replace `maxThreads` and `maxForks` with a single `maxWorkers` option. If both values were set with different numbers (one for threads pool, one for forks pool), pick the value matching the pool the project actually uses — `maxWorkers` is pool-agnostic in v4.
|
|
160
|
+
- [ ] Replace `singleThread: true` or `singleFork: true` with `maxWorkers: 1, isolate: false`.
|
|
161
|
+
- [ ] If `singleThread: false` or `singleFork: false` was set explicitly, just delete — it's the default.
|
|
162
|
+
- [ ] Move `poolOptions.{forks,threads}.execArgv` → top-level `execArgv`.
|
|
163
|
+
- [ ] Move `poolOptions.{forks,threads}.isolate` → top-level `isolate`.
|
|
164
|
+
- [ ] Move `poolOptions.vmThreads.memoryLimit` → top-level `vmMemoryLimit`.
|
|
165
|
+
- [ ] Remove `poolOptions.threads.useAtomics` (option removed).
|
|
166
|
+
- [ ] Remove `minWorkers` if present (option removed; behaves as if set to 0 in non-watch mode).
|
|
167
|
+
- [ ] Update CI environment variables: `VITEST_MAX_THREADS` and `VITEST_MAX_FORKS` → `VITEST_MAX_WORKERS`.
|
|
168
|
+
|
|
169
|
+
<fail_if note="pool flattening is pool-agnostic in v4; picking the wrong value silently changes concurrency">
|
|
170
|
+
Both `maxThreads` and `maxForks` are set with different numbers AND the project has no explicit `test.pool` you can use to decide which value `maxWorkers` should take. Do not guess. Write status: failed and ask the user which pool the project uses.
|
|
171
|
+
</fail_if>
|
|
172
|
+
|
|
173
|
+
#### 1.3 Workspace to Projects Rename
|
|
174
|
+
|
|
175
|
+
**Search Pattern**: `workspace` property in Vitest config files
|
|
176
|
+
|
|
177
|
+
**Changes Required**:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
181
|
+
export default defineConfig({
|
|
182
|
+
test: {
|
|
183
|
+
workspace: ['apps/*', 'libs/*'],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// ✅ AFTER (Vitest 4.0)
|
|
188
|
+
export default defineConfig({
|
|
189
|
+
test: {
|
|
190
|
+
projects: ['apps/*', 'libs/*'],
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Action Items**:
|
|
196
|
+
|
|
197
|
+
- [ ] Rename `workspace` property to `projects` in all config files.
|
|
198
|
+
- [ ] Inline any external `vitest.workspace.*` content into `test.projects` and delete the workspace file (external file references are no longer supported).
|
|
199
|
+
- [ ] If projects need different pool/environment options, set them inside each project entry rather than via the (now-removed) `poolMatchGlobs` / `environmentMatchGlobs` — see section 1.5.
|
|
200
|
+
|
|
201
|
+
<fail_if note="inlining is a semantic merge, not a copy">
|
|
202
|
+
The `vitest.workspace.*` file imports modules / calls functions / uses spreads that you cannot evaluate at edit time (dynamic project arrays, conditional imports). Write status: failed listing the file path and the dynamic shape that needs human resolution.
|
|
203
|
+
</fail_if>
|
|
204
|
+
|
|
205
|
+
#### 1.4 Browser Configuration
|
|
206
|
+
|
|
207
|
+
**Search Pattern**: `browser.provider`, `browser.testerScripts`, imports from `@vitest/browser`, `@vitest/browser/context`, `@vitest/browser/utils`
|
|
208
|
+
|
|
209
|
+
**Changes Required**: `browser.provider` is no longer a string. It's now the **return value of a provider function** imported from a per-provider package. Official packages:
|
|
210
|
+
|
|
211
|
+
- `@vitest/browser-playwright` — exports `playwright(options?)`
|
|
212
|
+
- `@vitest/browser-webdriverio` — exports `webdriverio(options?)`
|
|
213
|
+
- `@vitest/browser-preview` — exports `preview(options?)` (dev-only)
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
217
|
+
export default defineConfig({
|
|
218
|
+
test: {
|
|
219
|
+
browser: {
|
|
220
|
+
enabled: true,
|
|
221
|
+
provider: 'playwright', // string
|
|
222
|
+
testerScripts: ['./setup.js'], // array of scripts
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
import { page } from '@vitest/browser/context';
|
|
227
|
+
import { getElementError } from '@vitest/browser/utils';
|
|
228
|
+
|
|
229
|
+
// ✅ AFTER (Vitest 4.0)
|
|
230
|
+
import { defineConfig } from 'vitest/config';
|
|
231
|
+
import { playwright } from '@vitest/browser-playwright';
|
|
232
|
+
|
|
233
|
+
export default defineConfig({
|
|
234
|
+
test: {
|
|
235
|
+
browser: {
|
|
236
|
+
enabled: true,
|
|
237
|
+
provider: playwright({
|
|
238
|
+
launchOptions: { slowMo: 100 },
|
|
239
|
+
}),
|
|
240
|
+
instances: [{ browser: 'chromium' }],
|
|
241
|
+
testerHtmlPath: './test-setup.html', // single HTML path replaces script array
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
import { page, utils } from 'vitest/browser';
|
|
246
|
+
const { getElementError } = utils;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Action Items**:
|
|
250
|
+
|
|
251
|
+
- [ ] Install the appropriate provider package: `@vitest/browser-playwright`, `@vitest/browser-webdriverio`, or `@vitest/browser-preview`. Match whatever your `browser.provider` string was previously.
|
|
252
|
+
- [ ] Remove `@vitest/browser` from `dependencies`/`devDependencies` — its public surface moved into the main `vitest` package and the per-provider packages.
|
|
253
|
+
- [ ] Replace string `browser.provider: 'name'` with the function-call form: `provider: <providerFn>(<options>)`.
|
|
254
|
+
- [ ] Replace `browser.testerScripts: [...]` with `browser.testerHtmlPath: '<single-file>.html'`. Note: this is a **semantic** change (array of scripts → one HTML file). Move the script contents into a `<script>` block of the HTML file, or load them with `<script src>` references inside it.
|
|
255
|
+
- [ ] Update imports: `@vitest/browser/context` → `vitest/browser`; `@vitest/browser/utils` → `vitest/browser` (named export `utils`).
|
|
256
|
+
|
|
257
|
+
<fail_if note="provider package selection changes which browser tests actually run against">
|
|
258
|
+
The previous `browser.provider` string is dynamic (variable reference, ternary, or constructed at runtime) so you cannot determine which per-provider package to install. Write status: failed and ask the user which provider the project targets.
|
|
259
|
+
</fail_if>
|
|
260
|
+
|
|
261
|
+
#### 1.5 Deprecated Configuration Options
|
|
262
|
+
|
|
263
|
+
**Search Pattern**: `deps.external`, `deps.inline`, `deps.fallbackCJS` in config files
|
|
264
|
+
|
|
265
|
+
**Changes Required**:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
269
|
+
export default defineConfig({
|
|
270
|
+
test: {
|
|
271
|
+
deps: {
|
|
272
|
+
external: ['some-package'],
|
|
273
|
+
inline: ['inline-package'],
|
|
274
|
+
fallbackCJS: true,
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// ✅ AFTER (Vitest 4.0)
|
|
280
|
+
export default defineConfig({
|
|
281
|
+
test: {
|
|
282
|
+
server: {
|
|
283
|
+
deps: {
|
|
284
|
+
external: ['some-package'],
|
|
285
|
+
inline: ['inline-package'],
|
|
286
|
+
fallbackCJS: true,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Action Items**:
|
|
294
|
+
|
|
295
|
+
- [ ] Move `deps.*` options under `server.deps` namespace.
|
|
296
|
+
- [ ] Rename `deps.optimizer.web` → `deps.optimizer.client` (separate rename, same area).
|
|
297
|
+
- [ ] Remove `poolMatchGlobs` (use `projects` with conditions instead).
|
|
298
|
+
- [ ] Remove `environmentMatchGlobs` (use `projects` with conditions instead).
|
|
299
|
+
|
|
300
|
+
#### 1.6 Default Test File Exclusions Narrowed
|
|
301
|
+
|
|
302
|
+
**Search Pattern**: workspaces that have non-test files in `dist/`, `cypress/`, `.idea/`, `.cache/`, `.output/`, `.temp/`, or root config files (`rollup.config.*`, `prettier.config.*`, etc.) that look like test files.
|
|
303
|
+
|
|
304
|
+
**What Changed**: Vitest 4 excludes ONLY `node_modules` and `.git` by default. Previously, additional directories and root config files were excluded. Workspaces with `*.{spec,test}.*`-named files in those previously-excluded locations will see them picked up by the test runner in v4 unless an explicit exclusion is added.
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// To restore Vitest 3.x default exclusion behavior:
|
|
308
|
+
import { configDefaults, defineConfig } from 'vitest/config';
|
|
309
|
+
|
|
310
|
+
export default defineConfig({
|
|
311
|
+
test: {
|
|
312
|
+
exclude: [
|
|
313
|
+
...configDefaults.exclude,
|
|
314
|
+
'**/dist/**',
|
|
315
|
+
'**/cypress/**',
|
|
316
|
+
'**/.{idea,git,cache,output,temp}/**',
|
|
317
|
+
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*',
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Recommendation**: prefer `test.dir` to scope discovery for performance, instead of relying on negative exclusions.
|
|
324
|
+
|
|
325
|
+
**Action Items**:
|
|
326
|
+
|
|
327
|
+
- [ ] After upgrading, run `nx test <project>` for each affected project. If new test files surface unexpectedly from `dist/`, `cypress/`, etc., apply the snippet above or add a narrower exclude pattern.
|
|
328
|
+
- [ ] Consider setting `test.dir: './src'` (or equivalent) per project to scope discovery to source.
|
|
329
|
+
|
|
330
|
+
#### 1.7 Custom Environments: `transformMode` → `viteEnvironment`
|
|
331
|
+
|
|
332
|
+
**Applies when**: A project exports a custom Vitest environment (rare; check for files with `default export` of `{ name, setup, transformMode, ... }` consumed via `test.environment`).
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
336
|
+
export default {
|
|
337
|
+
name: 'my-env',
|
|
338
|
+
setup() {
|
|
339
|
+
/* ... */
|
|
340
|
+
},
|
|
341
|
+
transformMode: 'ssr',
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// ✅ AFTER (Vitest 4.0)
|
|
345
|
+
export default {
|
|
346
|
+
name: 'my-env',
|
|
347
|
+
setup() {
|
|
348
|
+
/* ... */
|
|
349
|
+
},
|
|
350
|
+
viteEnvironment: 'custom-env',
|
|
351
|
+
};
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Action Items**:
|
|
355
|
+
|
|
356
|
+
- [ ] If a custom environment file exists, rename its `transformMode` property to `viteEnvironment`.
|
|
357
|
+
- [ ] No change needed for workspaces using only built-in environments (`node`, `jsdom`, `happy-dom`, `edge-runtime`).
|
|
358
|
+
|
|
359
|
+
<fail_if note="viteEnvironment is not a value-for-value swap from transformMode">
|
|
360
|
+
The custom environment's `transformMode` value is something other than `'ssr'` or `'web'` (or its replacement Vite-environment name isn't obvious from the workspace). Write status: failed listing the file and the current `transformMode` value.
|
|
361
|
+
</fail_if>
|
|
362
|
+
|
|
363
|
+
### 2. Test Code Updates
|
|
364
|
+
|
|
365
|
+
#### 2.1 Mock Function Name Changes
|
|
366
|
+
|
|
367
|
+
**Search Pattern**: `.getMockName()` calls in test files
|
|
368
|
+
|
|
369
|
+
**Changes Required**:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
373
|
+
const mockFn = vi.fn();
|
|
374
|
+
expect(mockFn.getMockName()).toBe('spy'); // Old default
|
|
375
|
+
|
|
376
|
+
// ✅ AFTER (Vitest 4.0)
|
|
377
|
+
const mockFn = vi.fn();
|
|
378
|
+
expect(mockFn.getMockName()).toBe('vi.fn()'); // New default
|
|
379
|
+
|
|
380
|
+
// If you need custom names, set them explicitly
|
|
381
|
+
const namedMock = vi.fn().mockName('myCustomName');
|
|
382
|
+
expect(namedMock.getMockName()).toBe('myCustomName');
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Action Items**:
|
|
386
|
+
|
|
387
|
+
- [ ] Update test assertions checking default mock names from `'spy'` to `'vi.fn()'`
|
|
388
|
+
- [ ] Add explicit `.mockName()` calls where specific names are required
|
|
389
|
+
|
|
390
|
+
#### 2.2 Mock Invocation Call Order
|
|
391
|
+
|
|
392
|
+
**Search Pattern**: `.mock.invocationCallOrder` in test files
|
|
393
|
+
|
|
394
|
+
**Changes Required**:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
398
|
+
const mockFn = vi.fn();
|
|
399
|
+
mockFn();
|
|
400
|
+
expect(mockFn.mock.invocationCallOrder[0]).toBe(0); // Started at 0
|
|
401
|
+
|
|
402
|
+
// ✅ AFTER (Vitest 4.0)
|
|
403
|
+
const mockFn = vi.fn();
|
|
404
|
+
mockFn();
|
|
405
|
+
expect(mockFn.mock.invocationCallOrder[0]).toBe(1); // Now starts at 1 (Jest-compatible)
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Action Items**:
|
|
409
|
+
|
|
410
|
+
- [ ] Update assertions on `invocationCallOrder` to account for 1-based indexing
|
|
411
|
+
- [ ] Search for off-by-one errors in call order comparisons
|
|
412
|
+
|
|
413
|
+
#### 2.3 Constructor Spies and Mocks
|
|
414
|
+
|
|
415
|
+
**Search Pattern**: `vi.spyOn` on constructors, `vi.fn()` used as constructors
|
|
416
|
+
|
|
417
|
+
**Changes Required**:
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// ❌ BEFORE (Vitest 3.x) - Arrow function constructors might have worked
|
|
421
|
+
const MockConstructor = vi.fn(() => ({ value: 42 }));
|
|
422
|
+
new MockConstructor(); // May have worked in v3
|
|
423
|
+
|
|
424
|
+
// ✅ AFTER (Vitest 4.0) - Must use function or class
|
|
425
|
+
const MockConstructor = vi.fn(function () {
|
|
426
|
+
return { value: 42 };
|
|
427
|
+
});
|
|
428
|
+
new MockConstructor(); // Correctly supports 'new'
|
|
429
|
+
|
|
430
|
+
// Or use class syntax
|
|
431
|
+
class MockClass {
|
|
432
|
+
value = 42;
|
|
433
|
+
}
|
|
434
|
+
const MockConstructor = vi.fn(MockClass);
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**Action Items**:
|
|
438
|
+
|
|
439
|
+
- [ ] Convert arrow function mocks used as constructors to `function` keyword or `class` syntax
|
|
440
|
+
- [ ] Test all constructor spies to ensure `new` keyword works correctly
|
|
441
|
+
- [ ] Update any mocks that expect constructor behavior
|
|
442
|
+
|
|
443
|
+
#### 2.4 RestoreAllMocks Behavior
|
|
444
|
+
|
|
445
|
+
**Search Pattern**: `vi.restoreAllMocks()` in test files
|
|
446
|
+
|
|
447
|
+
**Changes Required**:
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
451
|
+
vi.mock('./module', () => ({ fn: vi.fn() }));
|
|
452
|
+
vi.restoreAllMocks(); // Would restore automocks
|
|
453
|
+
|
|
454
|
+
// ✅ AFTER (Vitest 4.0)
|
|
455
|
+
vi.mock('./module', () => ({ fn: vi.fn() }));
|
|
456
|
+
vi.restoreAllMocks(); // Only restores manual spies, NOT automocks
|
|
457
|
+
|
|
458
|
+
// To reset automocks, use:
|
|
459
|
+
vi.unmock('./module');
|
|
460
|
+
// or
|
|
461
|
+
vi.resetModules();
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Action Items**:
|
|
465
|
+
|
|
466
|
+
- [ ] Review all `vi.restoreAllMocks()` usage
|
|
467
|
+
- [ ] Add explicit `vi.unmock()` or `vi.resetModules()` calls for automocked modules
|
|
468
|
+
- [ ] Ensure test isolation is maintained after this change
|
|
469
|
+
|
|
470
|
+
#### 2.5 SpyOn Return Value Changes
|
|
471
|
+
|
|
472
|
+
**Search Pattern**: `vi.spyOn()` on already mocked functions
|
|
473
|
+
|
|
474
|
+
**Changes Required**:
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
478
|
+
const mock = vi.fn();
|
|
479
|
+
const spy = vi.spyOn({ method: mock }, 'method');
|
|
480
|
+
// spy !== mock (created new spy)
|
|
481
|
+
|
|
482
|
+
// ✅ AFTER (Vitest 4.0)
|
|
483
|
+
const mock = vi.fn();
|
|
484
|
+
const spy = vi.spyOn({ method: mock }, 'method');
|
|
485
|
+
// spy === mock (returns same instance)
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Action Items**:
|
|
489
|
+
|
|
490
|
+
- [ ] Review code that creates spies on existing mocks
|
|
491
|
+
- [ ] Remove redundant spy creation if same instance is returned
|
|
492
|
+
- [ ] Update assertions that check spy identity
|
|
493
|
+
|
|
494
|
+
#### 2.6 Automock Behavior Changes
|
|
495
|
+
|
|
496
|
+
**Search Pattern**: `vi.mock()` factories with getters, instance methods on automocked classes, `vi.restoreAllMocks()` usage when modules are automocked.
|
|
497
|
+
|
|
498
|
+
**Changes Required**:
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
502
|
+
vi.mock('./utils', () => ({
|
|
503
|
+
get value() {
|
|
504
|
+
return 42;
|
|
505
|
+
}, // getter executed
|
|
506
|
+
}));
|
|
507
|
+
|
|
508
|
+
import { value } from './utils';
|
|
509
|
+
console.log(value); // executes getter, prints 42
|
|
510
|
+
|
|
511
|
+
// ✅ AFTER (Vitest 4.0)
|
|
512
|
+
vi.mock('./utils', () => ({
|
|
513
|
+
get value() {
|
|
514
|
+
return 42;
|
|
515
|
+
},
|
|
516
|
+
}));
|
|
517
|
+
|
|
518
|
+
import { value } from './utils';
|
|
519
|
+
console.log(value); // getter NOT executed; prints undefined
|
|
520
|
+
|
|
521
|
+
// To spy on the getter explicitly:
|
|
522
|
+
vi.spyOn(utilsModule, 'value', 'get').mockReturnValue(42);
|
|
523
|
+
|
|
524
|
+
// Or define as a plain property (not a getter):
|
|
525
|
+
vi.mock('./utils', () => ({ value: 42 }));
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Additional behavior changes for automocked instance methods:
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
// Each instance gets its own mock for the same method name
|
|
532
|
+
const a = new AutoMockedClass();
|
|
533
|
+
const b = new AutoMockedClass();
|
|
534
|
+
a.method.mockReturnValue(42);
|
|
535
|
+
expect(a.method()).toBe(42);
|
|
536
|
+
expect(b.method()).toBeUndefined(); // independent per instance
|
|
537
|
+
|
|
538
|
+
// But the prototype is shared: a method mocked on the prototype affects all
|
|
539
|
+
// instances that don't have a per-instance mock.
|
|
540
|
+
AutoMockedClass.prototype.method.mockReturnValue(100);
|
|
541
|
+
b.method.mockReset(); // remove per-instance mock if any
|
|
542
|
+
expect(b.method()).toBe(100);
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
`vi.restoreAllMocks()` no longer touches automocks. Use `vi.unmock(modulePath)` or `vi.resetModules()` to clear an automocked module. **`.mockRestore()` on a single spy still works** (resets its implementation and clears state) regardless of whether the underlying module is automocked.
|
|
546
|
+
|
|
547
|
+
**Action Items**:
|
|
548
|
+
|
|
549
|
+
- [ ] Replace automocked **getters** that need to return values with plain property definitions, or add an explicit `vi.spyOn(obj, name, 'get').mockReturnValue(...)`.
|
|
550
|
+
- [ ] If a test relied on `vi.restoreAllMocks()` clearing an automocked module, add explicit `vi.unmock('./module')` or `vi.resetModules()` calls.
|
|
551
|
+
- [ ] Audit tests that mock instance methods of an automocked class; the per-instance independence may surface latent bugs.
|
|
552
|
+
- [ ] Do NOT remove `.mockRestore()` calls on single spies — they still work correctly.
|
|
553
|
+
|
|
554
|
+
#### 2.7 Settled Results Immediate Population
|
|
555
|
+
|
|
556
|
+
**Search Pattern**: `.mock.settledResults` in test files
|
|
557
|
+
|
|
558
|
+
**Changes Required**:
|
|
559
|
+
|
|
560
|
+
```typescript
|
|
561
|
+
// ✅ AFTER (Vitest 4.0)
|
|
562
|
+
const asyncMock = vi.fn(async () => 'result');
|
|
563
|
+
const promise = asyncMock();
|
|
564
|
+
|
|
565
|
+
// settledResults is immediately populated with 'incomplete' status
|
|
566
|
+
expect(asyncMock.mock.settledResults[0]).toEqual({
|
|
567
|
+
type: 'incomplete',
|
|
568
|
+
value: undefined,
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
// After promise resolves
|
|
572
|
+
await promise;
|
|
573
|
+
expect(asyncMock.mock.settledResults[0]).toEqual({
|
|
574
|
+
type: 'fulfilled',
|
|
575
|
+
value: 'result',
|
|
576
|
+
});
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Action Items**:
|
|
580
|
+
|
|
581
|
+
- [ ] Update tests that check `settledResults` before promise resolution
|
|
582
|
+
- [ ] Handle `'incomplete'` status in assertions
|
|
583
|
+
- [ ] Ensure tests properly await promises before checking settled results
|
|
584
|
+
|
|
585
|
+
### 3. Reporter and CLI Changes
|
|
586
|
+
|
|
587
|
+
#### 3.1 Reporter API Changes
|
|
588
|
+
|
|
589
|
+
**Search Pattern**: custom reporter classes/objects implementing any of these removed callbacks:
|
|
590
|
+
|
|
591
|
+
- `onCollected`
|
|
592
|
+
- `onSpecsCollected`
|
|
593
|
+
- `onPathsCollected`
|
|
594
|
+
- `onTaskUpdate`
|
|
595
|
+
- `onFinished`
|
|
596
|
+
|
|
597
|
+
**Changes Required**:
|
|
598
|
+
|
|
599
|
+
```typescript
|
|
600
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
601
|
+
export default {
|
|
602
|
+
onCollected(files) {
|
|
603
|
+
/* ... */
|
|
604
|
+
},
|
|
605
|
+
onTaskUpdate(task) {
|
|
606
|
+
/* ... */
|
|
607
|
+
},
|
|
608
|
+
onFinished(files) {
|
|
609
|
+
/* ... */
|
|
610
|
+
},
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// ✅ AFTER (Vitest 4.0)
|
|
614
|
+
// Use the new test-module / test-case event API. See:
|
|
615
|
+
// https://vitest.dev/api/advanced/reporters
|
|
616
|
+
// Typical replacements:
|
|
617
|
+
// onCollected → onTestModuleCollected
|
|
618
|
+
// onTaskUpdate → onTestCaseResult / onTestModuleEnd
|
|
619
|
+
// onFinished → onTestRunEnd
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Action Items**:
|
|
623
|
+
|
|
624
|
+
- [ ] Audit every custom reporter file for any of the five removed callbacks listed above. Each one needs replacement.
|
|
625
|
+
- [ ] Consult the v4 reporters API at https://vitest.dev/api/advanced/reporters for the exact replacement method name and signature.
|
|
626
|
+
- [ ] After rewriting, run the reporter in isolation against a small project to verify event delivery before applying workspace-wide.
|
|
627
|
+
|
|
628
|
+
<fail_if note="custom reporters carry external behavior the migration cannot deduce">
|
|
629
|
+
A reporter callback receives or emits data whose v4 equivalent you can't determine from the v4 reporters API alone (e.g., uses internal task tree shapes, depends on event ordering that has no v4 analogue). Write status: failed naming the reporter file and the callback; do not stub.
|
|
630
|
+
</fail_if>
|
|
631
|
+
|
|
632
|
+
#### 3.2 Built-in Reporter Changes
|
|
633
|
+
|
|
634
|
+
**Search Pattern**: `reporters: ['basic']`, `reporters: ['verbose']`
|
|
635
|
+
|
|
636
|
+
**Changes Required**:
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
640
|
+
export default defineConfig({
|
|
641
|
+
test: {
|
|
642
|
+
reporters: ['basic'],
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
// ✅ AFTER (Vitest 4.0)
|
|
647
|
+
export default defineConfig({
|
|
648
|
+
test: {
|
|
649
|
+
reporters: [['default', { summary: false }]], // Equivalent to 'basic'
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// For verbose (tree output)
|
|
654
|
+
reporters: ['tree']; // Use 'tree' for hierarchical output
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
**Action Items**:
|
|
658
|
+
|
|
659
|
+
- [ ] Replace `'basic'` reporter with `['default', { summary: false }]`
|
|
660
|
+
- [ ] Replace `'verbose'` reporter with `'tree'` for hierarchical output
|
|
661
|
+
- [ ] Update CI configuration if reporters are specified there
|
|
662
|
+
|
|
663
|
+
### 4. Snapshot Changes
|
|
664
|
+
|
|
665
|
+
#### 4.1 Custom Elements Shadow Root
|
|
666
|
+
|
|
667
|
+
**Search Pattern**: Snapshot tests involving custom elements or Web Components
|
|
668
|
+
|
|
669
|
+
**Changes Required**:
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
// ✅ AFTER (Vitest 4.0)
|
|
673
|
+
// Shadow root contents now printed by default in snapshots
|
|
674
|
+
|
|
675
|
+
// If you want old behavior (don't print shadow root):
|
|
676
|
+
export default defineConfig({
|
|
677
|
+
test: {
|
|
678
|
+
snapshotFormat: {
|
|
679
|
+
printShadowRoot: false,
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
});
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Action Items**:
|
|
686
|
+
|
|
687
|
+
- [ ] Review snapshot tests for custom elements
|
|
688
|
+
- [ ] Update snapshots if shadow root contents are now included
|
|
689
|
+
- [ ] Add `printShadowRoot: false` to `snapshotFormat` if old behavior is required
|
|
690
|
+
|
|
691
|
+
#### 4.2 `vi.fn` Snapshot String Changed
|
|
692
|
+
|
|
693
|
+
**Search Pattern**: `__snapshots__/**/*.snap` files containing `[MockFunction spy]`
|
|
694
|
+
|
|
695
|
+
**What Changed**: The default rendered string for an unnamed mock function in snapshots changed from `[MockFunction spy]` to `[MockFunction]`. Snapshots of mock objects taken in v3 will mismatch on re-run.
|
|
696
|
+
|
|
697
|
+
**Action Items**:
|
|
698
|
+
|
|
699
|
+
- [ ] Run tests with `--update` for projects that snapshot mock objects, then review the diff to confirm only the mock-name string changed.
|
|
700
|
+
- [ ] Where a specific mock name is asserted in snapshots, add explicit `.mockName('...')` calls.
|
|
701
|
+
|
|
702
|
+
#### 4.3 Custom Snapshot Matchers: Import Path Change
|
|
703
|
+
|
|
704
|
+
**Applies when**: A workspace defines custom snapshot matchers using `jest-snapshot`.
|
|
705
|
+
|
|
706
|
+
**What Changed**: Vitest 4 expects custom snapshot matchers to import from `vitest` (the new `Snapshots` namespace), not `jest-snapshot`.
|
|
707
|
+
|
|
708
|
+
```typescript
|
|
709
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
710
|
+
const { toMatchSnapshot } = require('jest-snapshot');
|
|
711
|
+
|
|
712
|
+
// ✅ AFTER (Vitest 4.0)
|
|
713
|
+
import { Snapshots } from 'vitest';
|
|
714
|
+
const { toMatchSnapshot } = Snapshots;
|
|
715
|
+
|
|
716
|
+
expect.extend({
|
|
717
|
+
toMatchTrimmedSnapshot(received: string, length: number) {
|
|
718
|
+
return toMatchSnapshot.call(this, received.slice(0, length));
|
|
719
|
+
},
|
|
720
|
+
});
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**Action Items**:
|
|
724
|
+
|
|
725
|
+
- [ ] Replace `require('jest-snapshot')` / `import 'jest-snapshot'` in custom matcher files with `import { Snapshots } from 'vitest'`.
|
|
726
|
+
- [ ] Remove `jest-snapshot` from `dependencies`/`devDependencies` if it's no longer used elsewhere.
|
|
727
|
+
|
|
728
|
+
### 5. Environment Variable Updates
|
|
729
|
+
|
|
730
|
+
**Search Pattern**: CI/CD configuration files, `.env` files, documentation
|
|
731
|
+
|
|
732
|
+
**Changes Required**:
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
# ❌ BEFORE (Vitest 3.x)
|
|
736
|
+
VITEST_MAX_THREADS=4
|
|
737
|
+
VITEST_MAX_FORKS=2
|
|
738
|
+
VITE_NODE_DEPS_MODULE_DIRECTORIES=/custom/path
|
|
739
|
+
|
|
740
|
+
# ✅ AFTER (Vitest 4.0)
|
|
741
|
+
VITEST_MAX_WORKERS=4
|
|
742
|
+
VITEST_MODULE_DIRECTORIES=/custom/path
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Action Items**:
|
|
746
|
+
|
|
747
|
+
- [ ] Update CI/CD pipeline environment variables
|
|
748
|
+
- [ ] Update `.env` files
|
|
749
|
+
- [ ] Update documentation referencing old environment variables
|
|
750
|
+
- [ ] Search for `VITEST_MAX_THREADS`, `VITEST_MAX_FORKS`, `VITE_NODE_DEPS_MODULE_DIRECTORIES`
|
|
751
|
+
|
|
752
|
+
### 6. Advanced: Module Runner Changes
|
|
753
|
+
|
|
754
|
+
**Search Pattern**: `vitest/execute`, `__vitest_executor`, `vite-node`
|
|
755
|
+
|
|
756
|
+
**Changes Required**:
|
|
757
|
+
|
|
758
|
+
```typescript
|
|
759
|
+
// ❌ BEFORE (Vitest 3.x)
|
|
760
|
+
import { execute } from 'vitest/execute';
|
|
761
|
+
// Access to __vitest_executor
|
|
762
|
+
|
|
763
|
+
// ✅ AFTER (Vitest 4.0)
|
|
764
|
+
// Use Vite's Module Runner API instead
|
|
765
|
+
// Consult Vite Module Runner documentation
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Action Items**:
|
|
769
|
+
|
|
770
|
+
- [ ] If using `vitest/execute`, migrate to Vite Module Runner
|
|
771
|
+
- [ ] Remove dependencies on `__vitest_executor`
|
|
772
|
+
- [ ] Update custom pool implementations (complete rewrite needed)
|
|
773
|
+
|
|
774
|
+
### 7. Type Definition Updates
|
|
775
|
+
|
|
776
|
+
**Search Pattern**: TypeScript imports from `vitest`, type errors after upgrade
|
|
777
|
+
|
|
778
|
+
**Changes Required**:
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
// All deprecated type exports removed
|
|
782
|
+
// If you get TypeScript errors about missing types:
|
|
783
|
+
// - Check if you're using deprecated type names
|
|
784
|
+
// - Update to current type names from Vitest 4 API
|
|
785
|
+
// - Remove explicit @types/node if it was only needed due to Vitest bug
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
**Action Items**:
|
|
789
|
+
|
|
790
|
+
- [ ] Run TypeScript compilation on all test files
|
|
791
|
+
- [ ] Fix any type errors related to removed Vitest type definitions
|
|
792
|
+
- [ ] Review `@types/node` usage (may no longer be accidentally included)
|
|
793
|
+
|
|
794
|
+
## Post-Migration Validation
|
|
795
|
+
|
|
796
|
+
1. Run tests per project: `nx test <project>`
|
|
797
|
+
2. Run all affected: `nx affected -t test`
|
|
798
|
+
3. Check coverage: `nx affected -t test --coverage`
|
|
799
|
+
4. Validate CI pipeline: `nx prepush`
|
|
800
|
+
|
|
801
|
+
Confirm:
|
|
802
|
+
|
|
803
|
+
- All configuration files updated
|
|
804
|
+
- All test files pass (or are flagged in your handoff `summary` if they remain failing — see `<test_integrity_guardrails>` below)
|
|
805
|
+
- Coverage reports generate correctly
|
|
806
|
+
- Environment variables updated
|
|
807
|
+
- No deprecated API warnings in console
|
|
808
|
+
|
|
809
|
+
<test_integrity_guardrails note="violating any of these masks regressions and defeats the migration's purpose">
|
|
810
|
+
|
|
811
|
+
- Do NOT force tests to pass by replacing test logic with `expect(true).toBe(true)`.
|
|
812
|
+
- Do NOT remove assertions to silence a failure.
|
|
813
|
+
- Do NOT add mocks that exist solely to make a failing test pass.
|
|
814
|
+
|
|
815
|
+
If a test cannot be made to pass within the scope of this migration, leave it failing and report it in your handoff `summary`.
|
|
816
|
+
|
|
817
|
+
</test_integrity_guardrails>
|