-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Problems with package.json
wildcard exports
#3201
Comments
Does
Keep in mind that this is a use case that TypeScript is not designed for, and which is known to not work well. There's a long thread with commentary from the TypeScript team which talks about this a bit if you're interested. Basically npm packages authored in TS are expected to publish generated JS code, not TS source code, because the behavior of that TS code depends on the TS compilation settings used at the time of authoring. To avoid behavior changes, these settings should be in control of the package author, not the package consumer. So the best solution here would probably be for this package to publish the generated JS files like it's supposed to be doing. |
Yes, this would let me import
ESM and CJS (
This is what's happening here. I would like to give more control (or have it myself) for applications that consume the package. Inlining, dead code elimination and conditional code (e.g. asserts) come to mind. Also debugging complex cases inside the app is so much easier/productive. So is the expected behavior of esbuild to NOT resolve a node module import from |
No I think it should be ok for esbuild to do this in this case, since there are no |
I agree that the actual file in the import should always be preferred. I did some more tests and found that TSC seemingly ignores the exports with But I'm not sure about how extensionless imports with |
I'm not sure exactly what you're saying by "ignores the exports" because you haven't provided a self-contained way to reproduce your issue. But I suspect that extensionless imports should not work if |
Sorry for not being clearer :) I was just pointing out a case when esbuild respects package.json exports and TSC does not. In the table Comparison with existing module resolution settings it is noted that the module resolutions So in this example it works with TSC but not with esbuild because TSC ignores the package.json export while esbuild, not knowing about the module resolution, respects it (if you delete the exports field from I'm actually fine with NOT supporting extensionless import paths for package.json exports but wanted to draw attention to this (slightly related) matter. My motivation was to reduce cases where TSC and esbuild differ in their behavior. |
I think perhaps esbuild shouldn't respect |
Fair point, I didn't think about it that way and I agree with using the |
Extensionless imports from packages are still possible. For example
Them importing |
Aren't all of these possible on JS files, at least if they're ESM? |
@evanw: The fix works great, thanks! I have tested multiple configurations and esbuild lines up with TSC now :)
Probably yes, but then the library would need to distribute the bundled files with defines (e.g. debug or trace) that would have been optimized away otherwise. In that case users of the library must take care of the optimizations themselves either way (if they don't want the performance penalty).
Yes! I have found that out as well. In the example from the OP you could import
With esbuild 0.18.12 the following would enable both imports
|
I'm curious what you mean, do you have an example? |
Sure, let's consider this example which is set up for release. The validation function is completly removed because esbuild recognizes that the if-condition is always false. For debug builds we would use Now we want users of this library to decide whether they want the runtime validation to happen or not. Then Arguably, we could ship additional debug bundles and I have seen some libraries doing it. But maybe we want multiple So I think it's reasonable to publish libraries with full release optimizations and include the original source files for advanced debugging scenarios or fine grained access. |
Hi!
redgeometry
is a hybrid ESM/CJS NPM package that also ships its source files. I realized that if the consuming application uses"moduleResolution": "Node16"
the package also needs to specify the export inpackage.json
. However, it looks like esbuild does not handle it correctly.Example project setup
./node_modules/redgeometry/package.json
(exports altered)./src/index.ts
./package.json
./tsconfig.json
TSC behaves as expected with the export, but esbuild complains:
If we change:
"type": "commonjs"
"moduleResolution": "Node"
import { Vector2 } from "redgeometry/src/primitives/vector"
(extensionless)Again, TSC is fine with that, but esbuild gives:
Interestingly, changing the export to
satisfies esbuild in this case.
But this obviously would not work for the original setup (
"moduleResolution": "Node16"
)...TSC:
esbuild:
It looks to me that esbuild does not apply the same rules when resolving those import paths. Is it reasoanble to expect that esbuild behaves similar to TSC in this case? Or is there a different solution that I am missing?
The text was updated successfully, but these errors were encountered: