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

Switch to ESM breaks 3rd party libraries #103

Closed
vladmandic opened this issue Oct 28, 2021 · 8 comments
Closed

Switch to ESM breaks 3rd party libraries #103

vladmandic opened this issue Oct 28, 2021 · 8 comments

Comments

@vladmandic
Copy link

Given the fact that long.js is used by 1m+, hard switch to ESM is ... well ... weird
Yes, those projects can pin version to 4.0, but that means that overall package updates (e.g. npm update --depth 1) to fix security vulnerabilities in less maintained projects breaks everything (which i've just experienced)

And asking 1m+ users to update their code is not realistic

Btw, official NodeJS roadmap places Stability as top-most priority:

Stability Policy
The most important consideration in every code change is the impact it will have, positive or negative, on the ecosystem (modules and applications).

@pauldraper
Copy link

pauldraper commented Oct 28, 2021

That's why it was a major version bump.

Because it has breaking behavior.

@dcodeIO
Copy link
Owner

dcodeIO commented Oct 28, 2021

I can relate to the frustration surrounding ESM and am open to hear this argument out, though I have to admit that so far I cannot quite follow the reasoning in the OP.

@vladmandic
Copy link
Author

vladmandic commented Oct 28, 2021

i agree its exactly how semver is supposed to work - major version bump for breaking change

for browsers, esm is definitely the way to go - no doubt
(also for nodejs typescript projects as tsc will do resolving)

however, i dont see a benefit of esm for off-the-shelf nodejs user
(yes, amd/umd are old, but need a working alternative, not just deal-with-it)

how to consume esm in nodejs?

  • standard import require that package is marked as type=module which is not always the case
  • dynamic imports are horrible at best and at worst they completely break type defs and intellicode
  • support for nodejs below 14 is what? and how many users are still on nodejs 12?
    i have 1k users, not 1m and i still get those questions often

perhaps if nodejs adopted import syntax as standard so we can get away from require completely, i'd be completely for it. but nodejs is what it is - and we're likely looking at distant future for this

what i do for my library is package both esm and cjs versions (and iife, but thats another story)

  • in browser import * from ... resolves to esm version
  • in nodejs, const x = require('..') resolves to cjs version

also, rules are slightly different when library has small number of users vs +1m like this one has
how many people run npm update --latest? i know i do. and every time i run into problems because of that, i fix it. but if only esm is packaged, there is no solution without modifying 3rd party libraries which is not an option

@dcodeIO
Copy link
Owner

dcodeIO commented Oct 29, 2021

One challenge I am seeing btw. is where the CommonJS module just exports a single class, here Long. What one basically wants for backwards-compatibility is to retain

const Long = require("long");

with an upgrade path of

import Long from "long";

which isn't exactly compatible, also when it comes to typings. What's the typical attack angle there?

For instance, for the former, typings are export = Long while for the latter it's export default Long.

@vladmandic
Copy link
Author

yes, its a challenge, but:

  • having both cjs and esm at least gives user options and having just esm is bad for nodejs users
    e.g. i could handle difference in import signature with packager preprocessing. not ideal, but workable.
  • old signature for backward compatibility can be achieved by having a separate js file that serves as re-export and is used as entry point when compiling for cjs target only

@dcodeIO
Copy link
Owner

dcodeIO commented Oct 29, 2021

I might me overlooking something, but it seems that if the package is ESM first, then having a CJS re-export is off the table due to the lack of top-level await. Or is there a way?

For reference, here is what I have so far.

@dcodeIO
Copy link
Owner

dcodeIO commented Oct 30, 2021

There is an UMD fallback now. Let me know if there are any issues :)

@dcodeIO dcodeIO closed this as completed Oct 30, 2021
@pauldraper
Copy link

Thanks! I agree the Node.js 12 support (EOL May 2022) is the compelling reason to add this; that's how I cam across this.

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

3 participants