top | item 44205706

(no title)

SCLeo | 8 months ago

Yeah, the commonjs to esm transition has been the python 2 to python 3 transition of JavaScript, except the benefits are limited (at least compared to the hassle created).

There are many libraries that have switched to esm only (meaning they don't support commonjs), but even today, the best way to find the last commonjs version of those libraries is to go to the "versions" tab on npm, and find the most downloaded version in the last month, and chances are, that will be the last commonjs version.

Yes, in a vacuum, esm is objectively a better than commonjs, but how tc39 almost intentionally made it incompatible with commonjs (via top-level awaits) is just bizarre to me.

discuss

order

eyelidlessness|8 months ago

It had to be incompatible with CommonJS regardless of top level await. There is no imaginable scenario where browsers would ship a module system with synchronous request and resolution semantics. A module graph can be arbitrarily deep, meaning that synchronous modules would block page load for arbitrarily deep network waterfalls. That’s a complete non-starter.

Given that, top-level await is a sensible affordance, which you’d have to go out of your way to block because async modules already have the same semantics.

Recently, Node has compromised by allowing ESM to be loaded synchronously absent TLA, but that’s only feasible because Node is loading those models from the file system, rather than any network-accessible location (and because it already has those semantics for CJS). That compromise makes sense locally, too. But it still doesn’t make sense in a browser.

apatheticonion|8 months ago

Bundler engineer here. ESM is great when it comes to build-time optimisations. When a bundler runs into CJS code it literally deopts the output to accommodate - so from that side it's amazing.

But also, there's a special place in hell for the people that decided to add default exports, "export * from" and top level await.

Commonjs is also very weird as a "module" instance can be reassigned to a reference of another module

module.exports = require('./foo')

and there's no way to do this in ESM (for good reason, but also no one warned us). In fact major projects like React use CJS exports and the entire project cannot be optimized by bundlers. So, rather than porting to ESM, they created a compiler LOL

sirsuki|8 months ago

If I may, the evil is not in the top level await but in the use of a top level await in a module that exports. That is evil. But a top level await in a programs main script seems ok to me.

pwdisswordfishz|8 months ago

> But also, there's a special place in hell for the people that decided to add […] top level await.

There is also a special place in extra-hell for those who export a function named 'then'.