Skip to content

Switch to ESM breaks 3rd party libraries #103

Closed

Description

@vladmandic

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).

Activity

  1. pauldraper commented on Oct 28, 2021

    @pauldraper

    That's why it was a major version bump.

    Because it has breaking behavior.

  2. dcodeIO commented on Oct 28, 2021

    @dcodeIO
    Owner

    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.

  3. vladmandic commented on Oct 28, 2021

    @vladmandic
    Author

    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

  4. dcodeIO commented on Oct 29, 2021

    @dcodeIO
    Owner

    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.

  5. vladmandic commented on Oct 29, 2021

    @vladmandic
    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
  6. dcodeIO commented on Oct 29, 2021

    @dcodeIO
    Owner

    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.

  7. dcodeIO commented on Oct 30, 2021

    @dcodeIO
    Owner

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

  8. pauldraper commented on Nov 1, 2021

    @pauldraper

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions