Build: Move vitest to repo root and upgrade to 4.1.0#34172
Conversation
Consolidate the two separate vitest setups (code/ and scripts/) into a single root-level vitest workspace config. This allows running all tests with a single `yarn test` from the repo root. Changes: - Add root vitest.config.ts that includes all projects from code/ and scripts/ - Remove code/vitest.config.ts (replaced by root config) - Add explicit configDir to storybook vitest plugin (needed for root context) - Update package.json scripts to run vitest from root - Merge NX test targets into a single target on the code project - Add ignoreSourceErrors to pseudo-states typecheck config
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughMigrate repository test infrastructure to Vitest: update root Vitest projects to use Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
📝 Coding Plan
Comment |
|
View your CI Pipeline Execution ↗ for commit 4e27527
☁️ Nx Cloud last updated this comment at |
- Replace redundant scripts/**/* input with vitest.config.ts (root config was missing from NX cache inputs; scripts already covered by sharedGlobals) - Restore storybook:vitest scripts to reference yarn test:watch/test instead of duplicating the full command
The CI jobs previously ran `yarn test` from `code/` working directory, passing test file paths relative to `code/`. After the vitest root migration, `yarn test` changes CWD to root, so file paths and output paths need to be relative to root. - Remove `working_directory: 'code'` from test jobs - Prefix glob patterns with `code/` (and add `scripts/` for unit tests) - Update test result persist paths from `code/test-results` to `test-results`
- Upgrade vitest and @vitest/* packages to ^4.1.0 - Add vite resolution to pin ^7.0.4 (vitest 4.1.0 pulls in vite 8.0.0 which breaks JSX transforms) - Update EXISTING_RESOLUTIONS for ecosystem-ci Note: test-manager.test.ts has 14 new failures due to vitest 4.1.0's module mocking changes (#9774: manual mocks no longer load/transform original modules). This test mocks vitest/node internals and needs a separate fix.
Vitest 4.1.0 changed module mocking behavior: importOriginal() in manual mocks no longer loads/transforms original modules (#9774). Remove the importOriginal() spread since the test only needs the createVitest mock — no other exports from vitest/node are used at runtime.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@code/addons/vitest/src/node/test-manager.test.ts`:
- Around line 47-49: The current vi.mock call directly returns an object for
createVitest; update it to use spy-mocking by passing { spy: true } to vi.mock
and return the export via vi.mocked(...) so tests use the repository's spy
convention. Specifically, replace the direct mock of createVitest with a
spy-enabled mock of 'vitest/node' and reference the mocked export using
vi.mocked(require('vitest/node')) or vi.mocked(importedModule) to map
createVitest to mockCreateVitest, ensuring mockCreateVitest remains the
implementation used by the spy.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fefe9dc1-7f49-4ca8-8b9e-2737b3d40b56
📒 Files selected for processing (1)
code/addons/vitest/src/node/test-manager.test.ts
- Remove ignoreSourceErrors from pseudo-states vitest config - Use yarn test in code/project.json NX target - Replace __dirname with import.meta.dirname in vitest.config.storybook.ts - Move vite from resolutions to devDependencies - Fix BrowserCommands type augmentation for vitest 4.1.0 compatibility
The addon had vitest ^4.0.14 while root had ^4.1.0, causing two separate copies with distinct BrowserCommands interfaces. Bump addon devDeps to ^4.1.0 and use the docs-recommended `declare module 'vitest/browser'` augmentation path.
Vitest now runs from root, so these were just delegating with `cd ..`. Updated storybook:vitest and ci-tests to call vitest directly, and updated AGENTS.md to reflect root-level commands.
Vitest runs from root, so these scripts belong there too.
Remove await-serve-storybooks, build, changelog, changelog:next, danger, github-release, and i scripts that are not referenced in any CI config or workflow.
This reverts commit e9cc2d3.
- eslint-plugin: derive rootDir from process.cwd() instead of hardcoding 'code' - react-docgen: mock process.cwd() to renderer directory so tsconfig resolution works from any vitest root
| "test": "cd .. && NODE_OPTIONS=--max_old_space_size=4096 vitest run --project scripts", | ||
| "test:watch": "cd .. && NODE_OPTIONS=--max_old_space_size=4096 vitest watch --project scripts", |
There was a problem hiding this comment.
You can also set these in Vitest config on project level:
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
projects: [
{
test: {
name: "scripts",
execArgv: ["--max_old_space_size=4096"]
}
}
]
},
});| "task": "jiti ./task.ts", | ||
| "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest run", | ||
| "test:watch": "NODE_OPTIONS=--max_old_space_size=4096 vitest watch", | ||
| "test": "cd .. && NODE_OPTIONS=--max_old_space_size=4096 vitest run --project scripts", |
There was a problem hiding this comment.
Instead of cd, you could use package manager's workspace commands.
I've set this kind of setup in https://github.com/chromaui/chromatic-e2e.
├── package.json
├── vitest.config.ts
│
└── packages
│
├── client
│ ├── package.json
│ └── vitest.config.ts
│
└── server
├── package.json
└── vitest.config.ts
/vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
projects: ["./packages"]
}
});/package.json
{
"name": "@scoped/monorepo-root",
"private": true,
"test": "vitest run",
}/packages/client/vitest.config.ts
import { defineProject } from "vitest/config"; // NOTE: defineProject, not defineConfig
export default defineConfig({
test: {
name: "Client Stuff",
environment: "jsdom",
// ... and so on
}
});/packages/client/package.json
{
"name": "@scoped/client",
"test": "yarn workspace @scoped/monorepo-root test --project 'Client Stuff'",
"Or depending on package manager": "",
"test": "pnpm --filter @scoped/monorepo-root test --project 'Client Stuff'",
"test": "npm --workspace @scoped/monorepo-root test -- --project 'Client Stuff'"
}/packages/server/vitest.config.ts
import { defineProject } from "vitest/config";
export default defineConfig({
test: {
name: "Server",
environment: "node",
// ... and so on
}
});/packages/server/package.json
{
"name": "@scoped/server",
"test": "yarn workspace @scoped/monorepo-root test --project Server",
}
What I did
Moved the vitest workspace config from
code/to the repo root and upgraded vitest to 4.1.0, socode/packages andscripts/tests all run from a single vitest invocation.Changes:
vitest.config.tsfromcode/to repo root, updated all project globs withcode/prefix, addedscripts/vitest.config.tsas a projectpackage.json:test,test:watch,storybook:vitest,storybook:vitest:inspectcode/package.json:test,test:watch,affected:test,storybook:vitest,storybook:vitest:inspectvitefrom resolutions to devDependenciesworking_directory: code)scripts/project.jsontest target (scripts tests now run via root vitest)BrowserCommandstype augmentation by deduplicating vitest across the monorepoprocess.cwd()beingcode/reactDocgenTypescript.test.ts(covered by other tests)AGENTS.mdto reflect root-level test commandsChecklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
yarn testfrom repo root — all tests pass (exceptdetect-agent.test.tswhich fails in any AI agent environment)yarn storybook:vitestfrom repo root — storybook browser tests run in watch modeDocumentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>