Skip to content

[vitest-pool-workers] Support require("./x.wasm?module") in CommonJS deps#14189

Open
tahmid-23 wants to merge 2 commits into
cloudflare:mainfrom
tahmid-23:fix/cjs-wasm-module-fallback
Open

[vitest-pool-workers] Support require("./x.wasm?module") in CommonJS deps#14189
tahmid-23 wants to merge 2 commits into
cloudflare:mainfrom
tahmid-23:fix/cjs-wasm-module-fallback

Conversation

@tahmid-23
Copy link
Copy Markdown

@tahmid-23 tahmid-23 commented Jun 4, 2026

Previously, only literal await import("./x.wasm?module") specifiers were rewritten through the static analysis path added in #11094. CommonJS dependencies that use require("./x.wasm?module") reach the module-fallback service at runtime, where the ?module suffix went unhandled. The fallback either failed with No such module "<abs>/x.wasm?module" or, when a CompiledWasm rule was configured, attempted to evaluate the WebAssembly bytes as JavaScript.

These require()s work in deployed workers because esbuild's bundler statically rewrites them into ES dynamic imports. vitest-pool-workers' Vite-based pipeline doesn't do that rewrite and instead defers to the module-fallback at runtime.

The module-fallback now strips ?module from the resolved target and synthesizes a CommonJS wrapper that re-requires the underlying .wasm by absolute path, exposing it on default to match what workerd produces for CompiledWasm modules.

Prisma 7 generates such require() statements on wasm?module imports. When running vitest under its default configuration, it prefers to load js-like extensions before ts-like extensions. Hence, this issue currently exists while running Prisma 7 with vitest-pool-workers, with the workaround being to reorder the extensions to prefer ts-like extensions first. This fix aims to make this workaround unnecessary (and support other possible packages that require() a wasm?module import.

It is possible to construct code, somewhat pathologically, that uses a require statement that the fallback server does not handle because we do not strip the ?module suffix from specifier. However, the example that I tried wouldn't actually resolve the imports when actually running the worker. Hence, I did not choose to strip the suffix from specifier, since I do not believe it is necessary for imports that actually resolve on workerd.


  • 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

A picture of a cute animal (not mandatory, but encouraged)


Open in Devin Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 4, 2026

🦋 Changeset detected

Latest commit: f4c2a37

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-pool-workers 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

@workers-devprod workers-devprod requested review from a team and emily-shen and removed request for a team June 4, 2026 20:25
@workers-devprod
Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/cjs-wasm-module-fallback.md: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/module-resolution/test/index.spec.ts: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/module-resolution/vendor/cjs-wasm-module-dep/add.wasm: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/module-resolution/vendor/cjs-wasm-module-dep/index.d.ts: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/module-resolution/vendor/cjs-wasm-module-dep/index.js: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/module-resolution/vendor/cjs-wasm-module-dep/package.json: [@cloudflare/wrangler]
  • fixtures/vitest-pool-workers-examples/package.json: [@cloudflare/wrangler]
  • packages/vitest-pool-workers/src/pool/module-fallback.ts: [@cloudflare/wrangler]
  • pnpm-lock.yaml: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

tahmid-23 and others added 2 commits June 5, 2026 16:49
…deps

Previously, only literal `await import("./x.wasm?module")` specifiers were
rewritten through the static analysis path added in cloudflare#11094. CommonJS
dependencies that use `require("./x.wasm?module")` reach the module-fallback
service at runtime, where the `?module` suffix went unhandled. The fallback
either failed with `No such module "<abs>/x.wasm?module"` or, when a
CompiledWasm rule was configured, attempted to evaluate the WebAssembly bytes
as JavaScript.

These `require()`s work in deployed workers because esbuild's bundler
statically rewrites them into ES dynamic imports. vitest-pool-workers'
Vite-based pipeline doesn't do that rewrite and instead defers to the
module-fallback at runtime.

The module-fallback now strips `?module` from the resolved target and
synthesizes a CommonJS wrapper that re-`require`s the underlying `.wasm` by
absolute path, exposing it on `default` to match what workerd produces for
CompiledWasm modules.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per .changeset/README.md, changeset titles shouldn't use `fix:`/`feat:`/etc
prefixes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@tahmid-23 tahmid-23 force-pushed the fix/cjs-wasm-module-fallback branch from 6a6dff5 to f4c2a37 Compare June 5, 2026 20:50
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.

2 participants