-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Module resolution: tsc unexpectedly rewrites the import path when exports field contains multiple entries resolving to the same file #56290
Comments
Oh, I should've noticed the pull request! Thanks for the fix. I've updated my reproduction repo with |
I noticed this when investigating #56261 and suspected this would happen. I don’t think it’s a bug per se, but I understand why it’s undesirable in this case. But I don’t know what rule you could make that would catch this. I think the main reason you’re expecting the inferred module specifier to be |
Thanks for the detailed explanation! I'll take this reply as a reference and make pull requests to both |
As both `./min` and `.` points to the same type definition file, sometimes TypeScript will resolve the type definition file to the `./min` key as it appears first. microsoft/TypeScript#56290 (comment) While this is not incorrect behavior, it breaks compatibility with older build environments that do not support the `exports` field. (e.g. TypeScript with `moduleResolution: "node"` instead of `bundler` or `node16`), as the `./min` entry is only available through the `exports` field. Some Vue.js users are experiencing this issue: vuejs/core#9521
Demo Repo
https://github.com/sodatea/ts-exports-rewrite
Which of the following problems are you reporting?
Something else more complicated which I'll explain in more detail
Demonstrate the defect described above with a code sample.
In the reproduction repo, the
parse.ts
file indirectly depends on thelru-cache
module's type by importing thecache.ts
file:After compilation, in
parse.d.ts
, we would normally expect aimport('lru-cache').LRUCache
expression.However, it actually becomes
import("lru-cache/min").LRUCache
.On the other hand, the compiled
cache.d.ts
file still imports fromlru-cache
, notlru-cache/min
.This seems to be related to
[email protected]
's exports field: https://unpkg.com/browse/[email protected]/package.json#L34It contains 2 entries,
./min
and.
, both pointing to the same file. TypeScript picks the first entry.If I modify the
exports
field to make.
appear before./min
, then the compiled declaration file would useimport("lru-cache")
as expected.While this isn't a very severe bug and has easy workarounds, this is quite unexpected.
Because
lru-cache/min
is an entry only available inexports
field, this compilation result breaks the compatibility with older build tools. And it is quite hard to debug, because no documentation ever mentioned that the order of keys in theexports
field would make a difference.Run
tsc --showConfig
and paste its output hereRun
tsc --traceResolution
and paste its output herePaste the
package.json
of the importing module, if it existsPaste the
package.json
of the target module, if it existsAny other comments can go here
Have a nice day!
The text was updated successfully, but these errors were encountered: