ts-node
ts-node copied to clipboard
`ts-node/esm` shortcircuits and does not allow downstream loaders to transform the result
Search Terms
short circuit, short-circuit, shortcircuit, essm, loader
Expected Behavior
The loader resolver should always pass the resolved URL to the next resolver (assuming it didn't already), without a shortcircuit. The loader should never shortcircuit anyway...
Actual Behavior
The lresolver/oader doesnot shortcircuit ever (I think...) and pass on its stuff to other loaders.
Steps to reproduce the problem
The repo https://github.com/codan84/jest-ts-experiments/tree/ava-testdouble uses Ava, TS, and TestDouble, to write a simple test. So it uses two loaders: ts-node/esm and testdouble.
When adding NODE_OPTIONS='--loader ts-node/esm --loader testdouble I noticed that ts-node/esm was shortciruiting the resolution and so the testdouble resolver did not get a change to add some query parameters to the URL. When debugging this, I noticed that the load also shortcircuits. I also noticed that it does shortcircuiting due to "laziness" (your words, not mine!).
- clone https://github.com/codan84/jest-ts-experiments/tree/9dd8449734a2d08fd13dd1fc6b7dbb1459a1cdce
npm install- Replace the
testscript to beNODE_OPTIONS='--no-warnings --loader=testdouble --loader=ts-node/esm' ava test/**/*.test.ts. - In
index.test.tsreplacetd.replaceEsm('../src/want-to-be-mocked.js')withtd.replaceEsm('../src/want-to-be-mocked.ts'). - Run
npm test
You will see the test succeed, whereas it should have failed. The reason it failed is that the mocking did not happen because resolution shortcircuited testdouble.
Minimal reproduction
See https://github.com/codan84/jest-ts-experiments/tree/9dd8449734a2d08fd13dd1fc6b7dbb1459a1cdce and above
Specifications
- ts-node version:
- node version: 10.9.1
- TypeScript version: 4.9.5
- tsconfig.json, if you're using one:
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "NodeNext",
"module": "ESNext",
"esModuleInterop": true,
"strict": true,
"rootDir": "./src",
"outDir": "./dist",
"skipLibCheck": true
},
"exclude": ["test/**"]
}
- package.json:
{
"name": "jest-ts-test",
"packageManager": "[email protected]",
"main": "dist/index.js",
"type": "module",
"scripts": {
"test": "NODE_OPTIONS='--no-warnings --loader=testdouble --loader=ts-node/esm' ava test/**/*.test.ts",
"build": "rm -rf dist && tsc"
},
"devDependencies": {
"@types/node": "^18.16.3",
"ava": "^5.2.0",
"testdouble": "^3.17.2",
"ts-node": "^10.9.1",
"typescript": "^4.3.0"
},
"dependencies": {
"image-type": "^5.2.0"
},
"ava": {
"extensions": {
"ts": "module"
}
}
}
- Operating system and version: Windows 11
- If Windows, are you using WSL or WSL2?: Yes, Ubuntu
You can see the initial issue that prompted this investation here: https://github.com/testdouble/testdouble.js/issues/514
A quick note about the short circuit logic: we always return the short circuit flag even when we don't short circuit. That flag doesn't trigger short-circuiting, it just tells node not to throw an error.
ts-node needs to ship a modified implementation of node's own default resolver, meaning it needs to come last in the chain. The resolution order should be:
import() -> your loader's resolve() -> ts-node's resolve() -> may use bundled, modified impl or may delegate to node's own default loader
Your loader should be able to call ts-node's resolver, then add query params to the response.