-
-
Notifications
You must be signed in to change notification settings - Fork 543
Description
Search Terms
ts-node, esm, ts-node-esm, yarn-pnp
Expected Behavior
Given:
- A TypeScript project...
- ...using ESM...
- ...and relative imports with extensions (as recommended for ESM)...
- ...with dependencies managed with Yarn PNP (and its own Node loader registered in runtime)
I shouldn't have problems running this TypeScript code with ts-node:
import { a } from './lib/a.js';
Command (actually a package.json script) being used:
yarn node --loader=ts-node/esm.mjs --loader=./.pnp.loader.mjs -- src/main.tsActual Behavior
$ yarn run test
(node:12796) [DEP0180] DeprecationWarning: fs.Stats constructor is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
node:internal/modules/run_main:123
triggerUncaughtException(
^
Error: Qualified path resolution failed: we looked for the following paths, but none could be accessed.
Source path: D:\dev\repro-ts-node-esm-yarn-pnp\src\lib\a.js
Not found: D:\dev\repro-ts-node-esm-yarn-pnp\src\lib\a.js
at makeError (D:\dev\repro-ts-node-esm-yarn-pnp\.pnp.cjs:5630:34)
at resolveUnqualified (D:\dev\repro-ts-node-esm-yarn-pnp\.pnp.cjs:7362:13)
at resolveRequest (D:\dev\repro-ts-node-esm-yarn-pnp\.pnp.cjs:7402:14)
at Object.resolveRequest (D:\dev\repro-ts-node-esm-yarn-pnp\.pnp.cjs:7458:26)
at resolve$1 (file:///D:/dev/repro-ts-node-esm-yarn-pnp/.pnp.loader.mjs:2043:21)
at nextResolve (node:internal/modules/esm/hooks:748:28)
at Hooks.resolve (node:internal/modules/esm/hooks:240:30)
at MessagePort.handleMessage (node:internal/modules/esm/worker:199:24)
at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:816:20)
at MessagePort.<anonymous> (node:internal/per_context/messageport:23:28)
Node.js v22.9.0
Steps to reproduce the problem / Minimal reproduction
Repro project: https://github.com/earshinov/repro-ts-node-esm-yarn-pnp/
The error is seen in the GitHub actions workflow: https://github.com/earshinov/repro-ts-node-esm-yarn-pnp/actions/
Specifications
$ yarn run ts-node -vv
ts-node v10.9.2 # 👈 latest
node v22.9.0
compiler v5.6.3
$ yarn --version
4.5.1
tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src",
"declaration": true,
"module": "ESNext",
"moduleResolution": "bundler",
"noImplicitReturns": true,
"outDir": "dist",
"rootDir": "src",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "ESNext"
},
"include": [
"src/**/*.ts"
]
}
package.json:
{
"name": "repro-ts-node-esm-yarn-pnp",
"private": true,
"packageManager": "yarn@4.5.1",
"type": "module",
"scripts": {
"test": "yarn node --loader=ts-node/esm.mjs --loader=./.pnp.loader.mjs -- src/main.ts",
"test-with-custom-resolver": "yarn node --loader=ts-node/esm.mjs --loader=./.pnp.loader.mjs --loader=./helpers/resolve-js2ts.mjs -- src/main.ts"
},
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "~5.6"
}
}
- Operating system and version: Windows 11 Version 2382 (OS Build 22631.4602)
- Running on the host, no WSL
Workaround
Using a dump custom resolver. Command:
yarn node --loader=ts-node/esm.mjs --loader=./.pnp.loader.mjs --loader=./helpers/resolve-js2ts.mjs -- src/main.tsCustom resolver:
export function resolve(specifier, context, nextResolve) {
console.log(`resolve-js2ts: ${specifier}`);
if (!specifier.endsWith('.js')) {
return nextResolve(specifier, context);
}
return Promise.resolve(nextResolve(specifier, context)).catch((err) => {
return Promise.resolve(nextResolve(specifier.replace(/\.js$/, '.ts'), context)).catch(() => {
throw err;
});
});
}Output:
$ yarn run test-with-custom-resolver
(node:47096) [DEP0180] DeprecationWarning: fs.Stats constructor is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
resolve-js2ts: file:///D:/dev/repro-ts-node-esm-yarn-pnp/src/main.ts
resolve-js2ts: ./lib/a.js
a
References
#1361 - most relevant piece of information I have found. Judging by the fact that the issue is closed and the relevant pull requests have been merged, it would seem that the problem has been fixed >1 year ago, except it apparently wasn't. Or maybe I'm dumb and there is another trap somewhere (as it usually is when it comes to Node.js, Yarn PNP, TypeScript and ESM).
✨Solution ✨
Do not pass --loader=./.pnp.loader.mjs when running yarn node, yarnpkg/berry#6645 (comment)