As of v22.12.0, Node.js added support for synchronous require of ESM dependency graphs.
This feature is a huge win for the interoperability of the CommonJS and ESM module ecosystems in
Node, but toolchains have yet to provide first-class support for this feature.
For example, TypeScript 5.7.3 (latest release) currently throws an error even with
compilerOptions.moduleResolution set to nodenext (ref microsoft/TypeScript#60534).
The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("global-directory")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts' or create a local package.json file with `{ "type": "module" }`.ts(1479)
In this demo repository, I'm focusing on how the current versions of Jest (29.7.0) and Vitest (3.0.3)
handle interop for require(esm).
✅ The code in index.ts runs via tsx
npm start
> require-esm-test@1.0.0 start
> npx tsx index.ts
/Users/erick.zhao/.nvm/versions/node/v22.13.0
❌ Jest fails
npm run test:jest
/Users/erick.zhao/Developer/dump/require-esm-test/node_modules/global-directory/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import process from 'node:process';
^^^^^^
SyntaxError: Cannot use import statement outside a module
✅ Vitest passes
npm run test:vitest
> require-esm-test@1.0.0 test:vitest
> npx vitest run index-vitest.spec.ts
RUN v3.0.3 /Users/erick.zhao/Developer/dump/require-esm-test
stdout | index-vitest.spec.ts
/Users/erick.zhao/.nvm/versions/node/v22.13.0
✓ index-vitest.spec.ts (1 test) 1ms
✓ index > should return true