The biggest issue with ESM is that it’s mostly theoretical design, approved without any POC confirmation that it can work effectively in real world scenarios we deal with today (on both server and browser).
The attitude was if I remember correctly: “let’s ship what we have now, and discuss use cases we *already* have later”. I don’t remember any other part of a standard shipped that way. Due that it’s probably most broken part of ECMAScript we have to deal with.
The .mjs is just another failed attempt (that as you noticed makes it even worse), to fix something that’s not really fixable if some previous agreements are not invalidated and looked through again
Brain already put it. Big mistake was that CJS was not on the table, when designing ESM. CJS was and still is a standard for a server.
It actually should have been added as an annex to ES specification, and on top of that ESM could have been specified in a way that can fully replace CJS, so ESM in turn can be used with success on both server an browser.
In similar way e.g. `__proto__` was treated. Thing that was never a standard, but got broad support. It was taken to annex and `Object.setPrototypeOf` was added as a standard.
It believe that if server-side case (CJS) would be treated by TC39 as first class citizen, the Node.js 6 would already ship with ES Modules, and CJS would already be history.
Are you aware that ESM as introduced to Node.js (putting aside all it’s flaws) are introduced to be a second (inferior to CJS) modules format with no intention to replace CJS? How can we accept that? Why do we need two formats on server side? Why something standard cannot be better than CJS, to get in as a valid replacement?
Now, you’re asking people to push packages so they can work only via
@std/esm Don’t you think it just adds to existing the mess? At best it’ll have same damaging effect as .mjs.
With .mjs suddenly babel transpiled ESM doesn’t work as expected, while with forced
@std/esm suddenly Node.js on its own will stop working. I personally will immediately throw away such package from my stack.
Concerning browsers, I disagree that we should accept transpilation step as something normal. It’s true that production environment needs optimizations (as minification etc), but for development (prior Babel based tooling) it was never natural to work with forced transpilation, at best we worked with bundling.
Forced transpilation in local development is main reason behind JS fatigue we deal these days with. We can reduce that by promoting effective local development setup which does not require any transpilation. So newcoming devs can see that their code being run 1:1 in the engines (without any wrapper that makes it “smarter” on the way, which just makes them feel lost).
ESM should be runnable efficiently without transpilation in the browsers, in a same way as CJS is. CJS requires just bundling, where modules code can be ported 1:1 with no transpilation implied (it’s e.g. how I work with browser projects today).
ESM as not bundlable format is also not worth consideration on browser side, It was already proven that even with HTTP2 we cannot have same level of efficiency as via bundle on the fly produced by server.
Therefore it seems that ESM as we deal with now is doomed. It should be brought back to TC39 table, together with CJS, and redesigned without looking back too much on what was already approved.
If I would call for any action it would be stick to CJS for now, and abandon ESM until it’s revisited & fixed by TC39