-
-
Notifications
You must be signed in to change notification settings - Fork 529
ESM is hell, how do we escape hell? #1346
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
Comments
Are you using Node in ESM mode ( |
No, because my package is part of 50 others that would all have to move. It was impossible when I was using Jest, but I've switched to vitest which maybe would work better. But ESM just poops on everything it touches, unless it touches everything. |
I mean, like it or hate it, ESM is the standard module system now, and CJS will phase out eventually. It’s not that ESM itself is the issue, but the end result of a fractured ecosystem of CJS <> ESM isn’t fun for anyone. Everything will migrate to ESM, but it will just take time. In the meantime, I can ship a CJS build for openapi-fetch until people are able to migrate. But CJS isn’t/won’t ever be the first-class citizen for support because ESM is the format that now runs universally in browsers / Node / Deno / etc. |
Yeah - I was thinking the same. I don't know why openapi-fetch seems to be the "thing that breaks" so often - I guess because you're trying to do it right and ship a flexible package... |
I don't have a setup right now, but you might try to change the file extension to ".mts"
then import this file using an function main() {
const openapiFetch = await import('openapi-fetch')
} |
Hm so I forgot we added this, but we actually do ship a CJS build already. Modern versions of Node (14+) should just “work” and pick up on the right thing. If not, it may be outdated build tooling, perhaps? Some old versions of webpack don’t follow the current spec (and honestly I haven’t used even webpack 5 so I can’t say what that does) |
Are you using openapi-fetch in a Node.js Express server without bundler? So that TS is emitting the end-output? Your tsconfig states that your project's input files are ESM but since you do not have |
Yes, that should be the case. Our service is NOT esm, thus not type: module, so we just want the CJS module to get selected. And it DOES sometimes, but not all the time. Like VSCode for example shows a pile of errors about type resolutions that don't happen at runtime. |
Ok but then your config seems alright for what you want to achieve. One would think that ts would simply pick up the CJS build of openapi-fetch. According to the TypeScript Documentation, the package.json of openapi-fetch does seem to have two issues:
This might potentially be the problem. Could you maybe edit the package.json of openapi-fetch in your node_modules accordingly and check if that would fix the problem? |
Ok, so here's an example. I have updated openapi-fetch from 0.7.5 (patched to remove type: module) to 0.7.6 (also attempted to patch similarly but with no luck), and now it does this:
I don't want to do either of these things, I just want it to import the cjs version. I have no idea why it won't. I can fix this by setting module to CommonJS and moduleResolution to Node in tsconfig, but this still seems like it should work as is. |
Alright I had a coffee and created a tiny repo to reproduce your setup: https://github.com/marcomuser/cjsts/tree/upstream. Indeed, I ran into this exact same ts error you mentioned. In order to fix this, one has to adjust the openapi-fetch build step a tiny bit. The problem is that typescript looks for a index.d.cts file to describe the index.cjs CommonJS output. Currently, openapi-fetch outputs a single index.d.ts for both the index.cjs and index.js files. This works for ESM projects but not for CommonJS projects. I fixed this in my error reproduction repo by moving the CommonJS file in its own cjs subdirectory and duplicating plus renaming the index.d.ts file to index.d.cts. Finally, I changed the exports field in openapi-fetch's package.json to point to the correct location for both ESM and CJS. Check this commit: marcomuser/cjsts@ea1ae14. I tried this setup and it works for both CJS and ESM projects in typescript! To fix this upstream, I think we need to adjust a) the package.json and b) make the build step output a cjs subdirectory and make sure that it includes both an index.cjs and an index.d.cts file. |
In my nextjs + typescript + jest usecase, I'd get this error:
and was able to fix it by setting
jest.config.ts: follow nextjs guide, then
|
Description
I struggle to even come up with a description other than "something is wrong with openapi-fetch that causes it to be almost impossible to use in a typical Typescript project. I know this is never ending frustration for everyone, but I'm hoping perhaps someone can spot the problem. I'm using express, node20, and vitest.
Reproduction
Here's the TS config:
Expected result
Not this error:
(using dynamic import doesn't help either)
Checklist
The text was updated successfully, but these errors were encountered: