Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Dec 23, 2025

Summary

Adds tests that verify @php-wasm/* and @wp-playground/* packages can be bundled with Vite for both browser and Node.js targets. This catches bundler-related issues like #3074 ("createRequire is not a function").

ES Modules tests:

  • Web bundle with static ESM imports (@php-wasm/web, @php-wasm/universal) - verified in Puppeteer
  • Node bundle with static ESM imports (@php-wasm/node, @php-wasm/universal)
  • Node bundle with dynamic ESM imports

CommonJS tests:

  • Node bundle with require() (@php-wasm/node, @php-wasm/universal)
  • Node bundle with dynamic import() in CJS context
  • Web bundle from CJS require() for browser target - verified in Puppeteer

Each test:

  1. Builds a bundle with Vite without externalizing dependencies
  2. Loads the bundled output:
    • Node bundles are loaded via import() or require()
    • Web bundles are loaded in a real browser via Puppeteer
  3. Verifies the smoke test passes (checks console logs)

Closes #3074

Test plan

  • CI passes on the test-built-npm-packages job
  • Bundler tests run successfully for both ESM and CommonJS flavors
  • Web bundles load without errors in Puppeteer

Tests that @php-wasm/* and @wp-playground/* packages can be bundled with Vite
for both browser and Node.js targets using various import styles.

ES Modules tests:
- Web bundle with static ESM imports (@php-wasm/web, @php-wasm/universal)
- Node bundle with static ESM imports (@php-wasm/node, @php-wasm/universal)
- Node bundle with dynamic ESM imports

CommonJS tests:
- Node bundle with require() (@php-wasm/node, @php-wasm/universal)
- Node bundle with dynamic import() in CJS context
- Web bundle from CJS require() for browser target

Each test builds a bundle with Vite (without externalizing dependencies) and
loads it to verify no immediate errors occur. This catches issues like the
"createRequire is not a function" error from #3074.
@adamziel adamziel marked this pull request as draft December 23, 2025 21:14
Web bundles are now loaded in a real browser via Puppeteer to verify they
work correctly. The test creates a simple HTML page that loads the bundle,
intercepts console logs and errors, and verifies the smoke test passes.

This catches browser-specific bundling issues that wouldn't be caught by
just verifying the build succeeds.
When viteExternalDynamicImports returned just a string, Rollup would resolve
it relative to the source file location. This caused paths like ./shared/icu.dat
to become ./lib/extensions/intl/shared/icu.dat in the output.

By returning an object with { id, external: true }, Rollup uses the path as-is
without further resolution, producing the correct ./shared/icu.dat path.
Jest was running PHP version tests in parallel, causing multiple tests
to try binding to the same port simultaneously. Using --runInBand forces
sequential execution, matching how the ESM tests already work.
Like the ESM tests, spawn a new Node process for each PHP version to avoid
V8 crashes and port conflicts when calling runCLI() multiple times. This
replaces the Jest-based approach with a simple custom test runner.
This avoids EADDRINUSE conflicts when tests run sequentially but the
previous server hasn't fully released the port yet.
WASM, SO, and DAT files are loaded at runtime, not bundled inline.
Node.js builtins should be external when targeting Node.js.
This fixes V8 heap crashes from trying to inline huge WASM files
and missing export errors from trying to bundle Node.js APIs for browser.
- Add --allow-file-access-from-files and --disable-web-security flags
  to Puppeteer to fix CORS errors when loading ES modules from file://
- Look for both .js and .mjs extensions when finding bundled output
- Include file list in error message for better debugging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ php-wasm-web ] CreateRequire is not a function

2 participants