privatenumber / tsx

⚡️ TypeScript Execute | The easiest way to run TypeScript in Node.js
https://tsx.is
MIT License
9.66k stars 154 forks source link

Running from non-project-root fails to resolve tsconfig "paths" #482

Open sou-long opened 8 months ago

sou-long commented 8 months ago

Acknowledgements

Minimal reproduction URL

https://stackblitz.com/edit/node-hpyz3n

Version

4.7.0

Node.js version

18.18.2

Package manager

yarn

Operating system

Windows

Problem & Expected behavior

What happened?

I added a custom path into tsconfig.json: "paths": {"@/*": ["./*"]}. Then if I run tsx index.ts in a project directory, all ok. If I run it from other directory, as the linked stackblitz already does (see .stackblitzrc):

cd ..
node-hpyz3n/node_modules/.bin/tsx node-hpyz3n/index.ts

then tsx cannot resolve modules referred to by "@/", e.g. import "@/other.js".

This prevents using tsx as a loader for cli tools of projects that use tsconfig paths, as in:

// cli.ts
#!/usr/bin/env tsx
import "@/other.js"
...

// package.json
{
  "bin": {"my-tool":"cli.ts"},
  ...
}

// shell
$ cd my-project
$ yarn link
$ cd /some/other/path
$ my-tool

This behavior doesn't seem to depend on path template names (@, @src, without @, etc).

What did you expect instead?

For tsx to resolve tsconfig paths based on a resolved project root, e.g. tsconfig.json/compilerOptions/{rootDir,baseUrl}. Or maybe based on tsconfig.json's location.

So, basically, if regular imports work relative to the importing source file, tsconfig-paths imports, being baseUrl-relative in normal circumstances, should work relative to where tsconfig.json thinks the root is. I believe there's no reason to resolve modules outside of a project root.

Do you have an error stack trace?

Error: Cannot find module '@/other.js'
Require stack:
- /home/projects/node-hpyz3n/index.ts
    at Module._resolveFilename (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:54:12642)
    at d.default._resolveFilename (file:///home/projects/node-hpyz3n/node_modules/.pnpm/@esbuild-kit+cjs-loader@2.4.0/node_modules/@esbuild-kit/cjs-loader/dist/index.js:1:1529)
    at Module._load (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:54:10056)
    at Module.require (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:54:13775)
    at i (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:98:2198)
    at _0x16f7fc (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:352:194520)
    at eval (file:///home/projects/node-hpyz3n/index.ts:2:132)
    at Object.eval (file:///home/projects/node-hpyz3n/index.ts:3:3)
    at Object.function (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:352:195362)
    at Module._compile (https://nodehpyz3n-b5hh.w-credentialless.staticblitz.com/blitz.6f234770.js:54:14871) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/home/projects/node-hpyz3n/index.ts' ]
}

Do you have documentation links? Do you have screenshots?

Nope.

Contributions

roysandrew commented 8 months ago

Duplicates https://github.com/privatenumber/tsx/issues/265 I think

privatenumber commented 8 months ago

Please fix your reproduction to:

sou-long commented 8 months ago

Done. A nested dir doesn't work with stackblitz due to path issues, but I modified .stackblitzrc so it takes the described steps and reproduces the issue immediately.

sjoholma commented 2 months ago

Workaround seems to be setting the TSX_TSCONFIG_PATH env manually before running tsx e.g. export TSX_TSCONFIG_PATH=./tsconfig.json && tsx index.ts