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

[ERR_REQUIRE_ESM] with openapi-fetch #1102

Closed
1 task done
thebuilder opened this issue May 8, 2023 · 10 comments · Fixed by #1176
Closed
1 task done

[ERR_REQUIRE_ESM] with openapi-fetch #1102

thebuilder opened this issue May 8, 2023 · 10 comments · Fixed by #1176
Labels
openapi-ts Relevant to the openapi-typescript library

Comments

@thebuilder
Copy link

Description

The openapi-fetch currently exports a index.js and (.index.min.js) file, which might work fine if run in a type: 'module' environment.

However, this is something that will be bundled for the browser environment, which leads to the joy of bundling, and could also be bundled for CommonJS for the client.
Exporting both a CommonJS and ESM file, and having them indexed correctly in the package.json should help with this.

A package like tsup should improve it. I think a simple setup like this should be enough.

{
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsup src/index.tsx"
  }
}

Error message

Error [ERR_REQUIRE_ESM]: require() of ES Module /Frontend/node_modules/.pnpm/openapi-fetch@0.1.2/node_modules/openapi-fetch/dist/index.js from /Frontend/dist/prerender/prerender.js not supported.
Instead change the require of index.js in /Frontend/dist/prerender/prerender.js to a dynamic import() which is available in all CommonJS modules.

Checklist

@thebuilder thebuilder mentioned this issue May 8, 2023
3 tasks
@drwpow
Copy link
Contributor

drwpow commented May 9, 2023

Thanks for submitting this, and for raising a PR!

However, this is something that will be bundled for the browser environment, which leads to the joy of bundling, and could also be bundled for CommonJS for the client.

Why would a client be built in legacy CommonJS any more? That’s a deprecated module system I’d rather not support. Vite, esbuild, webpack 5, and turbopack have all since moved onto ESM. Browsers support ESM natively now (you don’t even need to bundle this library!) and Node supports ESM natively now; why should this library support legacy systems?

@thebuilder
Copy link
Author

It's totally fair - And it might very well just my usecase that fails to consume it. I still need to bundle our node package as .cjs (using Vite), so it can be consumed by our Node tooling.

I still think there's some value in using a tool like tsup to bundle the output, since it just ensures it's ready for consumption by everyone, and supporting .cjs output doesn't have an impact on how you otherwise build the package.

@drwpow
Copy link
Contributor

drwpow commented May 11, 2023

I understand. And appreciate the effort you took in bundling using that! I will evaluate it and kick the tires on it. For additional context, this library was originally only shipping CJS, and then CJS + ESM for a while, but we had issues piling up on both CJS and ESM where fixing one issue would break the other (more typing issues than runtime code, but don’t discount runtime code, either—it’s technically separate code that has to be tested too!). And as you probably know, TypeScript itself has horrible support for packaging multi-target builds (for example there’s no option to output .cjs or .mjs file extensions, and they said they will probably never support it, and thus begins the rabbit hole of annoying tool maintenance just for bare-bones Node support). And since Sindre Sorhus dropped CJS support for all his packages back in 2021 I thought, hey, maybe we can just give up CJS and use ESM. And for the most part, users of openapi-typescript have used ESM just fine (I guess because it’s mostly used as a CLI tool).

Anyways, that was a long way to say I’ll evaluate tsup and see if it wouldn’t regress some interop issues users were having, and appreciate the work on this!

@thebuilder
Copy link
Author

Sounds good. Might also be worth to expose the exports and types field in package.json, just to help tools pick out the right files.

@drwpow
Copy link
Contributor

drwpow commented May 11, 2023

Oh if only it were that easy! 😅

@thebuilder
Copy link
Author

Nothings easy in the world of node modules

@drwpow drwpow added the openapi-ts Relevant to the openapi-typescript library label May 22, 2023
@djMax
Copy link

djMax commented May 24, 2023

Jest, React Native, Typescript, webpack, open telemetry - they all might work on their own with the right config, but all together? Forget it. Don't let this module be the thing that forces a decision on module systems.

@thebuilder
Copy link
Author

https://publint.dev/openapi-fetch@0.2.0

I think the exports needs to be added.
Is this even the right repo, or is it the standalone repo for Openapi-fetch? Why is the code located in two places?😄

@matthewvolk
Copy link

This would be incredibly helpful, for what it's worth. I'm building a Typescript API client that must be imported by a legacy CommonJS project. Unfortunately, I can't get creative with dynamic imports, either.

+1 to this thread, if possible! 🙂

@matthewvolk
Copy link

I found an interim workaround for my use case: This allows me to bundle my Typescript NPM package with openapi-fetch while allowing it to be consumed by both CJS and MJS projects, as well as other Typescript projects. Install tsup (npm i tsup -D) and add the following config:

// tsup.config.ts

import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['path/to/your/entry/file.ts'],
  format: ['cjs', 'esm'],
  noExternal: ['openapi-fetch'],
  dts: true,
  clean: true,
  platform: 'node',
});

The noExternal flag includes openapi-fetch in the Typescript build output, effectively "bypassing" the fact that openapi-fetch is only made available as a module.

Run add the following to your package.json:

"type": "module",
"main": "./dist/index.cjs",
"types": "./dist/index.d.ts",
"exports": {
  ".": {
    "import": "./dist/index.js",
    "require": "./dist/index.cjs",
    "types": "./dist/index.d.ts"
  }
},

Run npx tsup and you'll be able to import your package as CJS, MJS, or in a TS project even though it depends on openapi-fetch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
openapi-ts Relevant to the openapi-typescript library
Projects
None yet
4 participants