-
-
Notifications
You must be signed in to change notification settings - Fork 481
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
Request: update docs for recommended programmatic usage post-ESM #888
Comments
I’d be in favor of adding this. It might be easier if I wrote the docs, but I’d love to source info from people:
There won’t be a one-size-fits-all recommendation to people because all of these individual choices likely affect the fix. But with enough info we can probably have enough recommendations for most people to find something that works. There are just many factors! Unfortunately, ESM errors are all a side-product of a runtime completely replacing its module system, and it’s messy and frustrating for all involved (no shade at all to the Node team; I think they’re doing a wonderful job! It’s just an incredibly-hard problem dealing with upgrading the largest open software repository in history) |
would be great |
@drwpow I can answer your questions but with the caveat that my case is a little bit of a special case. For us, we're using this project in a JS script file that runs on-build to generate an API types file. We could So the answers to your questions for our use of this project:
I guess this might be off topic but I'm curious why this package has to ship with only ESM rather than with both ESM and CJS side-by-side? I use tsdx for my OSS libraries and I know it supports the ability to ship packages that have both structures exposed? |
I'm running into this when trying to import the package from within (I can create a TS script file within my main project which is already TS. But that complicates things, so I prefer to generate OpenAPI TS files before transpiling source files in the project.) |
I spent a few hours fighting with this today and came up with my own answers to your questions.
To second what @zackdotcomputer said: the answers to these questions don't really matter. The state of ESM is pretty terrible and, to quote a similar issue in a completely different project, "esm-only dependencies are user-hostile". For this project in particular, most of the use-cases is probably going to end up being it-looks-like-esm-but-it-runs-like-cjs-on-the-fly-compilation, so I'd strongly request publishing a ESM and CJS builds as part of your release process. |
@ianwremmel I have only dabbled with |
Also for a little more context, this library was originally shipped as CJS several years ago, but for a brief period did ship CJS + ESM, but dropped that because both users were having problems (especially when you throw TypeScript in the mix). Believe it or not, it’s not a simple “just use X to build” solution (I actually have experience with this, having worked on Snowpack which was the precursor to Vite). Any libraries that have had good CJS + ESM support (which are rare—many libraries still just ship good quality CJS and broken ESM) have earned it the hard way by fixing dozens if not hundreds of issues. But there’s always another “doesn’t work with X” bug lying in wait. I’m open to taking a second look at shipping a companion CJS build again; it was just dropped at a time when I knew I didn’t have the resources to maintain both shipped bundles and the core library, but also had more dependencies (like Prettier) that made bundling for multiple targets tricky. Now that this library is virtually dep-free I think it should be a much easier support story, and one we could tackle. |
First off, let me apologize for coming off harshly yesterday. The state of ESM is really frustrating and, worse, most of the projects that have moved to ESM-only seem to be the ones that are used in scenarios where it's least helpful (e.g., ESM is mostly only valuable for things that need to be tree-shaken when bundle size really matters) and hardest to work around (e.g., stuff that'll end up in CLIs). Without a lot of mucking with internals, many CLIs have their own built-in ways of on-the-fly compilation that are hard or impossible to avoid. The following come to mind, but I've encountered others:
All that being said, I've been shipping CJS, ESM, and types pretty successfully in this monorepo. Admittedly, I'm the only consumer 😂. The build commands are as simple as
and esbuild $FILES --format=esm --outdir=$DIST_DIR/esm --platform=node --sourcemap=external and tsc --project path/to/tsconfig.json #tsconfig should list $DIST_DIR/types as its output directory and then package.json contains an export map: {
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"types": "./dist/types"
},
"./package.json": "./package.json"
},
} With this setup, it's important to remove
|
No need to apologize—you didn’t come across harshly at all! 🙂 I feel your frustration, and I have invested a lot of my life in the CJS <> ESM compatibility interop outside of this project. I completely understand where you’re coming from! A bit irrelevant, but what you described is the exact reason why I moved away from Jest > Vitest; webpack > Vite; etc etc personally. Storybook has gotten half-Vite support, but it has also been a major source of frustration because it is still hard-tied to webpack in areas. But that said, I know that what works for me may not be possible for others, and it’s wrong to assume a solution to a problem is “just replace X with Y.” Anyways, I do believe it is this library’s responsibility to make it easy to consume. But I still believe in an ESM-first ecosystem as a universal module standard for Node & web, with CJS being a tack-on to support legacy systems. But that belief, again, is unhelpful to users experiencing pain, to all your points. And as a person who has had a lot of pain in that area myself, I empathize and am not writing it off. |
And yes—this is a great example of one of the many problems that make shipping multi-target builds hard for CJS + ESM with full TypeScript support for both 🙃 |
Update: published another attempt at an ESM + CJS bundle at Also, thanks for everyone speaking on this issue. It was worth looking into again, because several barriers to publishing a good CJS package were removed from the last attempt. |
Looks like it works, thanks! |
Right now the README explains how to import and use the openapiTS function for programmatic usage, but doesn't give context around how to do so for folks who are on LTS node or ts-node with default settings (i.e. did not have
"type": "module"
in their package.json and are just trying to run animportTypes.ts
script withts-node
).I think that ESM is just now becoming the default but the tooling around it is still pretty early and confusing between the prompts to add
"type": "module"
fighting withts-node
suddenly forgetting how to read TS files when you do. It would be nice to not only provide guidance on what should go in one'simportTypes
script but also the recommended way to run it now that the 5.x releases are shipping without a CJS copy.The text was updated successfully, but these errors were encountered: