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

TS should provide a way to patch buggy package.json files of dependents (ESM use of "moduleResolution": "nodenext" is not plausible during transition from CJS to ESM) #49388

Open
rosskevin opened this issue Jun 4, 2022 · 3 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@rosskevin
Copy link

rosskevin commented Jun 4, 2022

Bug Report

πŸ”Ž Search Terms

ESM
project.json main
exports

πŸ•— Version & Regression Information

4.7.2 this is new and experimental according to the handbook

⏯ Playground Link

https://github.com/rosskevin/ts-esm-workspaces/tree/apollo-exports

πŸ’» Code

"moduleResolution": "nodenext" vs "moduleResolution": "node" for modules targeting pure ESM output is not possible because ANY dependency that does not meet the standard e.g. properly defined exports will fail to build.

πŸ™ Actual behavior

We can use "moduleResolution": "node" to build a project with non-ESM dependencies, but we cannot use "moduleResolution": "nodenext" to build a project with any non-ESM dependency. IF you use "moduleResolution": "node", you MUST FAKE main behavior for typescript project references to build. This causes a multiplier effect of bad signals that a CJS main is present when that is clearly not the case.

If you have one single dependency that does not meet the spec, your build will fail and you cannot use "moduleResolution": "nodenext".

If a project has hundreds of dependencies, the likelihood it has A SINGLE DEPENDENCY that does not meet the ESM exports standard IS INCREDIBLY HIGH!

πŸ™‚ Expected behavior

In order to facilitate a transition to pure ESM modules, typescript should hybridize moduleResolution to allow a distinct transition period wherein faulty ESM targeted modules are allowed to be recognized, similar to node resolution.

@reference #49266 (comment)
@cc @milesj @weswigham

Ultimately, it seems like typescript MUST DECIDE TO BECOME an interop to allow for this transition period from CJS to ESM, otherwise it is bound to cause immense pain, 100x, to the community. Typescript is the vessel to mediate this issue, and I request they seek this as a primary goal. I agree that this is not to spec, but what about a flag? HOW did esModuleInterop come to pass? I request the same consideration. esmInterop: true should be a thing, shouldn't it?

@rosskevin rosskevin changed the title ESM use of "moduleResolution": "nodenext" is not plausible during transition ESM use of "moduleResolution": "nodenext" is not plausible during transition from CJS to ESM Jun 4, 2022
@weswigham
Copy link
Member

weswigham commented Jun 4, 2022

HOW did esModuleInterop come to pass?

To interoperate with babel modules. And babel designed it with the intent it would interoperate with real esm modules. But it doesn't, because of some parts of the node module interop scheme (like being completely unable to import esm synchronously). So, years of people planning to try to be compatible with what node can do just now and, ultimately, failing. :)

@weswigham
Copy link
Member

weswigham commented Jun 4, 2022

faulty ESM targeted modules are allowed to be recognized, similar to node resolution

node resolution doesn't have considerations like this - it just reflects the commonjs resolution algorithm circa node 10 or so. It pretty much reflects how your code will behave in old node.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jun 9, 2022
@weswigham weswigham added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. and removed Needs Investigation This issue needs a team member to investigate its status. labels Jun 13, 2022
@weswigham weswigham removed their assignment Jun 13, 2022
@weswigham weswigham changed the title ESM use of "moduleResolution": "nodenext" is not plausible during transition from CJS to ESM TS should provide a way to patch buggy package.json files of dependents (ESM use of "moduleResolution": "nodenext" is not plausible during transition from CJS to ESM) Jun 13, 2022
@weswigham
Copy link
Member

I've changed the title and tagging of this issue to reflect what I think the OP is essentially asking for. I'm not too bullish on something built into TS, though, since upstreaming a fix to the buggy package would be ideal, and following that, you could always patch the buggy package.json locally with something like patch-package. I don't think there's too much we could offer beyond this - export maps are just somewhat complicated and easily misused.

abrenneke added a commit to abrenneke/fp-ts-std that referenced this issue Nov 21, 2022
When using `nodenext` module resolution and there's an `exports` in the package.json, it requires a `types` field or else fails to resolve modules.

This adds `types` to `exports/./*` to resolve types for `import etc from 'fp-ts-std/etc'`, and changes the `.` import to an object so that types are correctly resolved for `import { etc } from 'fp-ts-std'`. Not sure why it didn't have an ESM import for `.` already, so added that too.

[Related TS issue](microsoft/TypeScript#49388)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants