Skip to content

[vitest-plugin] Pass the import kind to Vite so require() picks the require export condition - #16335

Open
robingenz wants to merge 4 commits into
cloudflare:mainfrom
robingenz:vitest-plugin-require-kind
Open

robingenz wants to merge 4 commits into
cloudflare:mainfrom
robingenz:vitest-plugin-require-kind

Conversation

@robingenz

@robingenz robingenz commented Oct 17, 2026 •

Copy link
Copy Markdown

Fixes #12984.
Fixes #13037.

On Vite 8, a require() in a CommonJS dependency resolved to the import entry of packages that ship both an import and a require entry. CommonJS code then got an ES module. With pg, for example, tests fail with SyntaxError: Cannot use import statement outside a module.

Why

viteResolve() in the module fallback service told Vite about a require() only through custom: { "node-resolve": { isRequire } }. Vite 7's resolve plugin reads that hint. Vite 8 uses rolldown's native viteResolvePlugin instead, and nothing reads the hint anymore. The native plugin picks require or import from the kind of each call. We passed no kind, so every lookup counted as an import.

Before rolldown 1.2.1, a kind passed from JS never reached the native plugin (rolldown/rolldown#10403). That is why #13062 had to rescan the exports map after resolution. rolldown/rolldown#10440 fixed this in rolldown 1.2.1, and Vite 8.3.0 and later require rolldown ~1.2.6. So passing kind is now enough, and the resolver does the work itself.

What

  • viteResolve() passes kind: "require-call" for a require() and kind: "import-statement" for an import.
  • It keeps custom["node-resolve"] for Vite 7 and earlier.
  • It calls vite.environments.ssr.pluginContainer.resolveId() instead of vite.pluginContainer.resolveId(..., { ssr: true }). Both reach the same container. The server-level pluginContainer forwards kind at runtime, but its type has no kind field, so the environment's container keeps this typed.

Vite 8 releases with rolldown older than 1.2.1 (8.0 and 8.1) stay affected. Updating Vite fixes them.

Test

  • New test in test/cjs-require.test.ts: a CommonJS package requires a dual-format package (import → index.mjs, require → index.cjs). The test expects the require entry. Without the fix it fails with expected 'esm' to be 'cjs'.
  • The fake Vite servers in test/module-fallback.test.ts now stub environments.ssr.pluginContainer. All 37 tests in that file pass.
  • I also applied the change to the built 1.4.0 package and ran a pg repro (the one in Vite 8 breaks importing pg in Vitest #12984). It fails before and passes after on Vite 8.3.0 and 8.3.4 with Vitest 4.1.11 and 5.0.3. It passes before and after on Vite 7.3.7.

  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: bug fix that restores the Vite 7 behaviour

🤖 Generated with Claude Code


Devin Review

Copilot AI balanced review requested due to automatic review settings October 17, 2026 15:47
@changeset-bot

changeset-bot Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9c44bf8

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

This PR includes changesets to release 1 package
Name Type
@cloudflare/vitest-plugin 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

@github-actions

This comment was marked as resolved.

@github-actions github-actions Bot closed this Oct 17, 2026
@github-project-automation github-project-automation Bot moved this from Untriaged to Done in workers-sdk Oct 17, 2026
@workers-devprod
workers-devprod requested review from a team and NuroDev and removed request for a team October 17, 2026 15:47
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/vitest-plugin-require-condition.md: [@cloudflare/wrangler]
  • packages/vitest-plugin/src/pool/module-fallback.ts: [@cloudflare/wrangler]
  • packages/vitest-plugin/test/cjs-require.test.ts: [@cloudflare/wrangler]
  • packages/vitest-plugin/test/module-fallback.test.ts: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused resolver fix preserves the legacy hint, includes regression coverage, and has no unresolved findings.

No open issues 🎉

What changed in this PR

Fixes CommonJS dependencies resolving to ESM exports on supported Vite 8 releases in the Workers Vitest integration.

Changes:

  • Passes import kind through Vite’s SSR environment resolver while preserving the legacy resolution hint.
  • Adds regression coverage and updates resolver stubs.
  • Adds a patch changeset.
File Description
packages/​vitest-plugin/​test/​module-fallback.test.ts Updates stubs to use the SSR environment container.
packages/​vitest-plugin/​test/​cjs-require.test.ts Tests CommonJS resolution of dual-format packages.
packages/​vitest-plugin/​src/​pool/​module-fallback.ts Passes the require/import kind to Vite.
.changeset/​vitest-plugin-require-condition.md Documents the resolution fix for release.

Review effort: Balanced

@petebacondarwin

Copy link
Copy Markdown
Contributor

OK let's re-open this and consider if it is the correct fix.

@github-project-automation github-project-automation Bot moved this from Done to Untriaged in workers-sdk Oct 20, 2026
@petebacondarwin
petebacondarwin requested review from petebacondarwin and removed request for NuroDev October 20, 2026 11:07
@petebacondarwin petebacondarwin self-assigned this Oct 20, 2026
@petebacondarwin petebacondarwin moved this from Untriaged to In Review in workers-sdk Oct 20, 2026
@clanky-the-clanker

Copy link
Copy Markdown

This pull request was not reviewed automatically because its author does not have write access to this repository. A maintainer with write access can start a review by commenting clanky review (or clanker review or @clanky-the-clanker review), optionally followed by instructions (e.g. clanky review focus on the retry logic).

@pkg-pr-new

pkg-pr-new Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@16335

@cloudflare/build-output-utils

npm i https://pkg.pr.new/@cloudflare/build-output-utils@16335

@cloudflare/codemods

npm i https://pkg.pr.new/@cloudflare/codemods@16335

@cloudflare/config

npm i https://pkg.pr.new/@cloudflare/config@16335

@cloudflare/containers-shared

npm i https://pkg.pr.new/@cloudflare/containers-shared@16335

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@16335

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@16335

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@16335

miniflare

npm i https://pkg.pr.new/miniflare@16335

@cloudflare/pages-functions

npm i https://pkg.pr.new/@cloudflare/pages-functions@16335

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@16335

@cloudflare/runtime-types

npm i https://pkg.pr.new/@cloudflare/runtime-types@16335

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@16335

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@16335

@cloudflare/vitest-plugin

npm i https://pkg.pr.new/@cloudflare/vitest-plugin@16335

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@16335

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@16335

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@16335

wrangler

npm i https://pkg.pr.new/wrangler@16335

commit: 9c44bf8

@petebacondarwin

petebacondarwin commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

clanker review

@petebacondarwin
petebacondarwin force-pushed the vitest-plugin-require-kind branch 2 times, most recently from 67802f2 to 9ad304d Compare October 23, 2026 13:19
@workers-devprod

workers-devprod commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • ✅ @cloudflare/wrangler
Show detailed file reviewers

robingenz and others added 2 commits October 23, 2026 15:31
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@petebacondarwin
petebacondarwin force-pushed the vitest-plugin-require-kind branch from 57d7ddb to 5e72806 Compare October 23, 2026 14:31

@petebacondarwin petebacondarwin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OK this LGTM.
Are we saying that this fix doesn't work on Vite 8.0.x, 8.1.x, and 8.2.0?
If so, I think we should mention that in the changeset.

Comment thread packages/vitest-plugin/src/pool/module-fallback.ts Outdated

@workers-devprod workers-devprod left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Codeowners reviews satisfied

@robingenz

Copy link
Copy Markdown
Author

Yes. The fix needs rolldown 1.2.1 or later (rolldown/rolldown#10440), and Vite 8.2.1 is the first release that ships it. Vite 8.0.x, 8.1.x and 8.2.0 stay affected. I added that to the changeset and applied your suggestion.

@github-project-automation github-project-automation Bot moved this from In Review to Approved in workers-sdk Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Approved

4 participants