Skip to content

feat: migrate to Vitest 4#8

Merged
ascorbic merged 9 commits intoascorbic:mainfrom
commoncurriculum:vitest-4-migration
Feb 20, 2026
Merged

feat: migrate to Vitest 4#8
ascorbic merged 9 commits intoascorbic:mainfrom
commoncurriculum:vitest-4-migration

Conversation

@scottmessinger
Copy link
Contributor

Fixes CJS compatibility with Vite 6's Module Runner, enabling Vitest 4 support.

Changes

  • Override Astro's ssr.noExternal: true in configResolved hook
  • Add CJS packages to ssr.external so Node.js loads them natively
  • Update import paths from @vitest/browser/* to vitest/browser
  • Update browser provider config to use playwright() function
  • Update README with Vitest 4 requirements and examples

The Problem

Astro sets ssr.noExternal: true which forces all packages through Vite 6's Module Runner. The Module Runner's ESModulesEvaluator doesn't support CJS packages (React, Vue, Svelte, picocolors), causing "module is not defined" errors.

The fix overrides this in configResolved to allow CJS packages to be loaded natively by Node.js.

Testing

All 39 browser tests pass including:

  • Pure Astro components
  • React hydrated components
  • Vue hydrated components
  • Svelte hydrated components
  • Interactive components with user events

Closes #7

scottmessinger and others added 2 commits February 5, 2026 15:15
Update all imports to use Vitest 4's new module structure:
- @vitest/browser/context -> vitest/browser
- @vitest/browser/utils -> vitest/browser (via utils export)
- Add @vitest/browser-playwright for browser provider
- Update provider config from string to function: playwright()
- Update peer dependency to vitest ^4.x

Build and unit tests pass. Browser tests are BLOCKED by a known
incompatibility between Vite 6's new SSR Module Runner and CommonJS
packages (picocolors, cssesc, react, vue, etc.). The Module Runner
uses ESModulesEvaluator which doesn't support `module.exports`.

This affects viteServer.ssrLoadModule() calls used to render Astro
components. The issue exists in both Astro 5.x and 6.x beta.

Related: vitejs/vite#16217
See PR ascorbic#7 comments for prior investigation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix CJS compatibility with Vite 6's Module Runner by overriding
  Astro's ssr.noExternal: true in configResolved hook
- Add CJS packages (react, vue, svelte, picocolors, etc.) to ssr.external
  so Node.js loads them natively instead of through ESModulesEvaluator
- Update import paths from @vitest/browser/* to vitest/browser
- Update browser provider config to use playwright() function
- Update README with Vitest 4 requirements and examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@scottmessinger
Copy link
Contributor Author

Hi @ascorbic! I just worked through this with claude and I think we figured it out.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@scottmessinger
Copy link
Contributor Author

@ascorbic I can confirm this branch works great!

Copilot AI review requested due to automatic review settings February 16, 2026 11:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the vitest-browser-astro package from Vitest 3 to Vitest 4, addressing critical CJS compatibility issues between Astro 5, Vite 6's Module Runner, and Vitest 4. The core fix overrides Astro's ssr.noExternal: true setting to allow CJS packages (React, Vue, Svelte, etc.) to be loaded natively by Node.js instead of being forced through Vite's Module Runner, which doesn't support CommonJS.

Changes:

  • Updated all Vitest imports from @vitest/browser/* to vitest/browser per Vitest 4 API changes
  • Changed browser provider configuration from string "playwright" to function playwright()
  • Implemented configResolved hook to externalize CJS packages and fix "module is not defined" errors
  • Updated all dependencies to Vitest 4.x and @vitest/browser-playwright
  • Added comprehensive test suite in basic.test.ts for pure Astro components

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-lock.yaml Updated Vitest from 3.2.4 to 4.0.18, replaced @vitest/browser with @vitest/browser-playwright, added CJS compatibility packages
packages/vitest-browser-astro/src/plugin.ts Added configResolved hook to override Astro's SSR config and externalize CJS packages
packages/vitest-browser-astro/src/index.ts Updated imports from @vitest/browser/context to vitest/browser
packages/vitest-browser-astro/src/pure.ts Updated imports and destructured utils from vitest/browser
packages/vitest-browser-astro/src/types.ts Updated type imports to vitest/browser
packages/vitest-browser-astro/package.json Updated Vitest peer dependency to ^4.x, added prepare script, moved @vitest/browser to @vitest/browser-playwright
packages/vitest-browser-astro/README.md Updated installation instructions, configuration examples, and version requirements for Vitest 4
packages/vitest-browser-astro/test/fixtures/astro-site/vitest.browser.config.ts Imported and used playwright() function for provider configuration
packages/vitest-browser-astro/test/fixtures/astro-site/test/browser.test.ts Updated userEvent import path to vitest/browser
packages/vitest-browser-astro/test/fixtures/astro-site/test/basic.test.ts New test file for pure Astro components with Vitest 4 import paths
packages/vitest-browser-astro/test/fixtures/astro-site/package.json Updated dependencies to Vitest 4 and @vitest/browser-playwright, added vite-plugin-cjs-interop
package.json Updated root Vitest dev dependency to ^4.0.0
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +187 to +196
// Ensure CJS packages are in the external list
const external = config.ssr.external;
if (Array.isArray(external)) {
for (const pkg of cjsPackages) {
if (!external.includes(pkg)) {
// @ts-expect-error - mutating readonly config to fix CJS compatibility
external.push(pkg);
}
}
}
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code only handles the case where config.ssr.external is already an array. If config.ssr.external is undefined, true, or a function (which are valid Vite config values), the CJS packages won't be added to the external list. Consider initializing the external array or handling these edge cases to ensure CJS packages are always externalized.

Copilot uses AI. Check for mistakes.
ascorbic and others added 5 commits February 16, 2026 11:49
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
….json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Removed unused dependencies from pnpm-lock.yaml.
This version update requires Vitest 4.
@changeset-bot
Copy link

changeset-bot bot commented Feb 20, 2026

🦋 Changeset detected

Latest commit: 88e2138

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
vitest-browser-astro Minor
astro-test-fixture Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ascorbic ascorbic merged commit 029b978 into ascorbic:main Feb 20, 2026
1 of 2 checks passed
@ascorbic
Copy link
Owner

Thanks!

@mixie-bot mixie-bot bot mentioned this pull request Feb 20, 2026
@scottmessinger
Copy link
Contributor Author

@ascorbic Thank you for merging this and also, I'm so sorry for not getting to the thing you mentioned me in! I saw the mention come and then promptly forgot 🤦‍♂️ Sorry about that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants