Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug?] [ts-node]: ts-node fails to resolve relative .js imports into .ts under Yarn PNP #6645

Open
1 task
earshinov opened this issue Jan 4, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@earshinov
Copy link

earshinov commented Jan 4, 2025

Self-service

  • I'd be willing to implement a fix

Describe the bug

Just reported this to ts-node (TypeStrong/ts-node#2148), but thought that the problem might lie on the Yarn PNP's side and you guys could take a look. Following is a copy of that bug report:


Search Terms

ts-node, esm, ts-node-esm, yarn-pnp

Expected Behavior

Given:

  1. A TypeScript project...
  2. ...using ESM...
  3. ...and relative imports with extensions (as recommended for ESM)...
  4. ...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.ts

Actual 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": "[email protected]",
  "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.ts

Custom 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

TypeStrong/ts-node#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 in ts-node >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).


To reproduce

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/

Environment

System:
  OS: Windows 11 10.0.22631
  CPU: (12) x64 Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz
Binaries:
  Node: 22.9.0 - C:\Users\EARSHI~1\AppData\Local\Temp\xfs-fde8a036\node.CMD
  Yarn: 4.5.1 - C:\Users\EARSHI~1\AppData\Local\Temp\xfs-fde8a036\yarn.CMD
  npm: 10.8.3 - C:\Program Files\nodejs\npm.CMD

Additional context

No response

@earshinov earshinov added the bug Something isn't working label Jan 4, 2025
@earshinov
Copy link
Author

Same issue with Yarn 4.6.0. Just updated the repro project to use the latest Yarn.
https://github.com/earshinov/repro-ts-node-esm-yarn-pnp/actions/runs/12610624380/job/35145402458

@earshinov
Copy link
Author

Running the same code with nodeLinker: node-modules succeeds:
https://github.com/earshinov/repro-ts-node-esm-yarn-pnp/actions/runs/12610983741/job/35146158434

Command:

yarn node --loader=ts-node/esm.mjs -- src/main.ts

Seems to be a Yarn PNP issue after all (or a ts-node issue manifesting itself only under Yarn PNP)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant