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

ExtensionlessRelativePath not compatible with Node10 Module Resolution #32

Closed
Kelerchian opened this issue Nov 8, 2023 · 2 comments
Closed

Comments

@Kelerchian
Copy link

Kelerchian commented Nov 8, 2023

TypeScript version 5.2 locks the configuration of module: "commonjs" to moduleResolution: "node10". I just realized that extensionless relative paths (e.g. import * as x from "x/subpath") doesn't work with package.json/exports field. This applies to old bundlers typescript support such has ts-loader 8 on webpack 4

If this is not within tshy's problem scope, let this issue act as a warning to those using node10 module resolution or libraries catering node10 customers.
However, if this is within tshy's problem scope, then I propose one possible solution.

The issue arises on multilayered dependency (A<-B<-C) where B resolves A through 'moduleResolution: node16' , and C resolves B and A through moduleResolution:node10.
C breaks because it cannot figure out A/subpath that is imported inside B's files.
Parts of A that are exposed by B to C turn into any.

// package B
// moduleResolution: node16 - works just fine
import * as a from "A/subpath"
export { a } from "A/subpath"; // reexport
export ... // other objects that uses `a`
// package B
// moduleResolution: node10 - `aSubpath` is of type `any`
import { aSubpath, ...restOfB } from "B";

Possible Solution

Subfolders containing package.json work but it must be on the root folder (inspiration).
For example, if the export configuration is:

"exports": {
      "./foo": "./src/foo.ts"
}

Then there must be an accompanying package json in:

root/
 - dist/
   - commonjs
     - foo.js
     - foo.d.ts
   - esm
     - foo.js
     - foo.d.ts
 - src/
 - foo/
   - package.json << here

This package.json must contain

{
  "main": "../dist/commonjs/foo.js",
  "module": "../dist/esm/foo.js",
  "types": "../dist/commonjs/foo.d.ts"
}

This works for node:10, however, the fact that the subfolder must exist in the root-level folder is intimidating because, when the generation and cleanup is automated, the subfolder name may conflict with existing folder.

Here's my makeshift fix for the node10 moduleResolution https://github.com/Kelerchian/systemic-ts-utils/blob/master/scripts/generate-node10-support.ts

@isaacs
Copy link
Owner

isaacs commented Nov 8, 2023

Yeah, to be honest, "moduleResolution": "node10" style is not likely to ever be supported by tshy.

It is unfortunate that as popular a tool as webpack does not support subpath exports at this time. I'm sure there are reasons, everyone tries to do their best to make rational choices, and I don't intend any shade towards webpack or any other tool. But it's been out over 4 years now, we have to move on at some point and use the current state of the platform rather than be held back by tools that do not move forward and adapt.

You can hack around it, as you show here, but I don't think it's appropriate for tshy to implement that affordance; as you say, it can cause problems if you have have a folder by that name already, and working around the caveats is too much effort just to keep working with a tool that is not updating. Probably you can write a little script that reads package.json exports and generates the appropriate folders, and use it alongside tshy. Might be useful for others in this position.

I think it would be appropriate for tshy to blow up if it detects an incompatible moduleResolution (or other tsconfig settings that will cause an incompatible moduleResolution to be implied). Patch welcome for that, you can take a look at the prevent-verbatim-module-syntax.ts module (used in tsconfig.ts) for an example of doing a similar check in a safe and correct way.

@Kelerchian
Copy link
Author

That's reasonable. Closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants