fix(vitest): generate root vitest.config.ts instead of deprecated vitest.workspace - #36316
Merged
Conversation
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
|
View your CI Pipeline Execution ↗ for commit 802a569
☁️ Nx Cloud last updated this comment at |
leosvelperez
force-pushed
the
gh-36311
branch
2 times, most recently
from
July 14, 2026 13:54
a86ffff to
b69b03e
Compare
Contributor
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud has identified a possible root cause for your failed CI:
This CI failure appears to be related to the environment or external dependencies rather than your code changes.
No code changes were suggested for this issue.
Trigger a rerun:
🎓 Learn more about Self-Healing CI on nx.dev
The @nx/vitest configuration generator wrote a root vitest.workspace.ts to aggregate the project configs. Vitest 4 removed workspace files, so that file is inert and its projects are never discovered. The generator now writes a root vitest.config.ts with the project globs under test.projects for vitest 4 (and when the installed version cannot be detected), keeping the workspace file only for the still-supported vitest 3. The aggregator excludes itself from its `**/vitest.config.*` glob via `!vitest.config.ts`; otherwise vitest resolves the root config as an extra project that, having no include of its own, re-runs every test through the default glob without each project's environment and setupFiles. Update the vue and nuxt application snapshots, the create-nx-workspace e2e assertion, and the tutorial file trees to the new file name.
The vitest 4 migration inlines a static vitest.workspace file into a root vitest.config under test.projects. The inlined `**/vitest.config.*` glob matched the new config itself, so vitest resolved the root config as an extra project. With no include of its own, that project re-ran every test through the default glob without each project's environment and setupFiles, duplicating runs and failing tests that depend on their own config. Both write paths now append a root-anchored negative glob excluding the root config file (`!vitest.config.<ext>`). The create path applies it unconditionally; the merge path (editing a pre-existing config) applies it only when the target has no own `test.include`, since a config that runs its own tests must stay in the project set. The negation only ever drops the root file and is inert when the globs don't match it. The AI migration instructions gain the same self-match check next to the existing duplicate-name one.
The vitest inference plugin matches any `**/{vite,vitest}.config.*` file, so a
root `vitest.config.ts` that only aggregates the project configs through
`test.projects` was inferred as a project rooted at the workspace root. The
existing guard zeroed that project's targets but still registered the node, so
`nx format` and affected detection treated the whole workspace as a single
project.
The plugin now skips inferring a project for a root orchestrator config, so the
aggregating config no longer produces a workspace-root project. A root config
without `test.projects` (a standalone project at the workspace root) is
unaffected and still gets a project.
The configuration generator picks between a v4 root vitest.config.ts, a v3 vitest.workspace.ts, and skipping when a root config already exists, but two branches of that selection had no direct coverage. Add tests that the generator skips writing vitest.config.ts when a root vite.config.ts is already present, and that it defaults to the v4 root-config shape when the installed vitest version cannot be detected.
…ng it Generating vitest config for a project wrote a root vitest.config.ts aggregator even when a root vite.config already existed. That aggregator wins vitest's config resolution, so the root vite config's settings (resolve.alias, plugins) no longer applied to vitest runs and the child projects don't inherit them; a spec resolving a root alias failed with ERR_MODULE_NOT_FOUND after generation. Skip the aggregator when a root vite.config or vitest.config already exists and leave it in place. Warn when that root config declares no `test.projects`, since the new project then runs through the root config without its own `environment`/`setupFiles`, and warn when the config's shape can't be read statically. When no root config exists the aggregator is still written, now excluding the root vite/vitest configs from the `test.projects` glob so a later-added root config isn't re-run as an extra default-glob project.
The vitest plugin returns null for a root config that only aggregates projects via `test.projects`, so it registers no project for it. That null result was never cached: the callback returned early before `targetsCache.set`, so every project-graph build re-ran `buildVitestTargets` for the root config, including a full vite `resolveConfig`. Widen the cache to hold null and store it like any other result, moving the no-node check to the cache-hit path. The config's hash still covers its contents, so a config that stops aggregating is re-evaluated.
…ests
Name the root-config classifier's return as a `'declares' | 'missing' |
'unknown'` union so the three cases read explicitly at the call sites and
a later truthiness check can't fold `'unknown'` in with the aggregating
case. Correct the aggregator comment to note its projects glob matches
the generated `vitest.config.ts` itself (excluded now), not only a root
`vite.config` added later.
Add a test for a root `vitest.config.ts` that already declares
`test.projects` (left untouched, no warning), and drop an unreachable
`?? {}` fallback in the plugin's no-node assertions.
polygraph-app
Bot
force-pushed
the
gh-36311
branch
from
July 15, 2026 15:57
528f2a9 to
802a569
Compare
FrozenPandaz
approved these changes
Jul 15, 2026
AgentEnder
pushed a commit
that referenced
this pull request
Jul 17, 2026
…est.workspace (#36316) ## Current Behavior The `@nx/vitest:configuration` generator writes a root `vitest.workspace.ts` to aggregate project configs. Vitest 4 removed workspace files, so that file is inert: its projects are never discovered and the tests never run. ## Expected Behavior For vitest 4 (and when the installed version can't be detected, since new installs resolve to v4) the generator writes a root `vitest.config.ts` with the project globs under `test.projects`, keeping `vitest.workspace.ts` only for the still-supported vitest 3. The root config excludes itself from its own `**/vitest.config.*` glob (`!vitest.config.ts`). Otherwise vitest resolves the root config as an extra project that, having no `include`, re-runs every test through the default glob without each project's `environment` and `setupFiles`. The `@nx/vite` `update-23-0-0` migration, which inlines existing workspace files into a root config, applies the same self-exclusion (skipping it when the target config has its own `test.include`). ## Related Issue(s) Fixes #36311 <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/gh-36311-96476507) <!-- polygraph-session-end -->
FrozenPandaz
pushed a commit
that referenced
this pull request
Jul 20, 2026
…est.workspace (#36316) ## Current Behavior The `@nx/vitest:configuration` generator writes a root `vitest.workspace.ts` to aggregate project configs. Vitest 4 removed workspace files, so that file is inert: its projects are never discovered and the tests never run. ## Expected Behavior For vitest 4 (and when the installed version can't be detected, since new installs resolve to v4) the generator writes a root `vitest.config.ts` with the project globs under `test.projects`, keeping `vitest.workspace.ts` only for the still-supported vitest 3. The root config excludes itself from its own `**/vitest.config.*` glob (`!vitest.config.ts`). Otherwise vitest resolves the root config as an extra project that, having no `include`, re-runs every test through the default glob without each project's `environment` and `setupFiles`. The `@nx/vite` `update-23-0-0` migration, which inlines existing workspace files into a root config, applies the same self-exclusion (skipping it when the target config has its own `test.include`). ## Related Issue(s) Fixes #36311 <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/gh-36311-96476507) <!-- polygraph-session-end --> (cherry picked from commit 33eeefb)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Current Behavior
The
@nx/vitest:configurationgenerator writes a rootvitest.workspace.tsto aggregate project configs. Vitest 4 removed workspace files, so that file is inert: its projects are never discovered and the tests never run.Expected Behavior
For vitest 4 (and when the installed version can't be detected, since new installs resolve to v4) the generator writes a root
vitest.config.tswith the project globs undertest.projects, keepingvitest.workspace.tsonly for the still-supported vitest 3.The root config excludes itself from its own
**/vitest.config.*glob (!vitest.config.ts). Otherwise vitest resolves the root config as an extra project that, having noinclude, re-runs every test through the default glob without each project'senvironmentandsetupFiles. The@nx/viteupdate-23-0-0migration, which inlines existing workspace files into a root config, applies the same self-exclusion (skipping it when the target config has its owntest.include).Related Issue(s)
Fixes #36311
View session information ↗