Description
Desired Behavior
Consider a source file src/package-a/index.ts
that will be transpiled by tsc to build/package-a/index.js
, and a package.json
that looks like this:
{
"type": "module",
"imports": {
"#package-a": "./build/package-a/index.js"
}
}
Now TypeScript allows me to import import {...} from #package-a
in any other file. Even when I am importing the generated .js
file (that maybe don't exists yet), TypeScript knows that file will be generated from the .ts
in src
and correctly type-check that file, uses it for editor support, etc.
ts-node
, however, doesn't know how to resolve the file and fails with
node_modules/ts-node/dist-raw/node-internal-modules-esm-resolve.js:366
throw new ERR_MODULE_NOT_FOUND(
[...]
The same occurs for subpath exports
: TypeScript resolves to the source file that will generate that .js
but ts-node
doesn't.
I would expect ts-node
to follow TypeScript semantics here and resolve to the corresponding .ts
file as the language server does.
Is this request related to a problem?
Using subpath imports (since v14, v12 in experimental) is a common practice to alleviate the burden of nested, relative paths, as well to provide "internal packages" and many other cases. TypeScript, with a well configured tsconfig.json
and package.json
, just works.
The issue is, you can't point to the .ts
file in the "imports"
field of the package.json
to make ts-node
works since that field will also be read by node
at runtime to resolve the import, so it must point to the generated .js
. This issue makes it really difficult to correctly use this Node feature.
Alternatives you've considered
My first idea was to use conditional imports so the package.json
could look something like this:
{
"type": "module",
"imports": {
"#package-a": {
"ts-node": "./src/package-a/index.ts",
"default": "./build/package-a/index.js"
}
}
}
However I can't figure out how to use a custom condition for ts-node
(I'm using ts-node-esm
but don't think that's relevant). I have tested with NODE_OPTIONS="-C ts-node" npx ts-node-esm thing
but got the same error. A possible workaround is to allow custom conditions and the last pattern should work, but I still think the original example should be supported by ts-node
out of the box (or at least via some config).
Additional context
I think the issue was commented on #1007, but that's a very long thread to follow a possible resolution there.