Skip to content

fix: preserve runtime createRequire in ESM builds#1334

Open
Jaksenc wants to merge 1 commit into
vercel:mainfrom
Jaksenc:fix/create-require-runtime
Open

fix: preserve runtime createRequire in ESM builds#1334
Jaksenc wants to merge 1 commit into
vercel:mainfrom
Jaksenc:fix/create-require-runtime

Conversation

@Jaksenc

@Jaksenc Jaksenc commented Jun 14, 2026

Copy link
Copy Markdown

Problem

Since 0.38.2, an ESM build can replace a runtime
createRequire(...) binding with undefined, causing the later runtime
require(...) call to throw.

Change

  • Disable Webpack's createRequire parser handling in ncc so Node evaluates
    the call at runtime.
  • Add a TypeScript ESM integration fixture that loads a runtime-selected JSON
    module and executes the emitted .mjs bundle.

This keeps the fix at ncc's Webpack configuration boundary and covers the
reported runtime behavior without changing dependency tracing.

Validation

  • node scripts/build.js --no-cache
  • node --expose-gc --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand -t 'should preserve runtime createRequire in ESM builds' test/integration.test.js
    • 1 passed
  • pnpm test -- test/unit.test.js
    • 28 passed
  • node --expose-gc --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand test/integration.test.js --testNamePattern='^(?!should execute "ncc run (?:canvas|sharp|socket\.io)\.js"$).*'
    • 67 passed; 3 local environment-dependent cases skipped
  • Negative control with Webpack's createRequire parsing restored reproduced
    the emitted undefined binding and runtime TypeError.

Risk

The parser option applies to all JavaScript handled by ncc. It intentionally
preserves createRequire for Node to evaluate at runtime, so modules selected
only at runtime must still be deployed with the bundle.

The cross-platform Node 22/24/26 matrix remains for CI. A local CLI watch test
failed with Watchpack EMFILE errors and reproduced identically on
origin/main, so it is not attributed to this change.

Out of scope

  • Changing how ncc traces or deploys runtime-selected modules.
  • Dependency or lockfile updates.

Issue linkage

Fixes #1312

Comment thread test/integration.test.js
try {
const { code, assets } = await ncc(input, {
cache: false,
esm: true,

@styfle styfle Jun 25, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did you add the programatic api here instead of cli because you want to set esm: true?

If thats the only reason, its probably best to rename the .ts file to .mts or set type:module in package.json instead.

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.

Regression: dynamic runtime require works in 0.38.1 but breaks in 0.38.2

2 participants