testdouble.js
testdouble.js copied to clipboard
replaceEsm breaks in node20 when other loaders are used
Description
I'm trying to use testdouble in a Typescript project using ESM modules, and I get a TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts
error when I try to use the replaceEsm function.
Issue
Assume a source file like the following, which tries to use replaceEsm before importing another typescript module, other.ts
:
import * as td from "testdouble";
await td.replaceEsm("fs");
await import("./other.js");
If I run this under a typescript loader like tsx
or ts-node/esm
, I get an error like the following:
> [email protected] withtestdouble
> tsx withtestdouble.ts
node:internal/process/esm_loader:34
internalBinding('errors').triggerUncaughtException(
^
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/jalf/src/repro/other.ts
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async nextLoad (node:internal/modules/esm/hooks:750:22)
at async Z (file:///Users/jalf/src/repro/node_modules/tsx/dist/esm/index.mjs:5:1644)
at async nextLoad (node:internal/modules/esm/hooks:750:22)
at async load (file:///Users/jalf/src/repro/node_modules/quibble/lib/quibble.mjs:140:7)
at async nextLoad (node:internal/modules/esm/hooks:750:22)
at async Hooks.load (node:internal/modules/esm/hooks:383:20)
at async MessagePort.handleMessage (node:internal/modules/esm/worker:199:18) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
If remove the replaceEsm call, it works fine.
Apparently the tsx and quibble loaders clash, somehow.
Environment
-
node -v
output: v20.9.0 -
npm -v
(oryarn --version
) output: 10.1.0 -
npm ls testdouble
version: [email protected]
Example Repo
https://github.com/jalfd/testdouble-repro
- run
npm run withtestdouble
to reproduce the problem. - run
npm run notestdouble
to see that it works if the replaceEsm call is removed