4 ms·
Still not clear to me what ESM exactly fixes. CJS works pretty well for me. The amount of pain ESM gives in unit tests is enough to ignore ESM. Maybe Bun will m
by wdb 3y ago
Still not clear to me what ESM exactly fixes. CJS works pretty well for me. The amount of pain ESM gives in unit tests is enough to ignore ESM. Maybe Bun will make a difference here.
- brundolf 3y agoBy being declarative instead of imperative: - The dependencies of a module can be scraped without running the code - The subset of declarations used in an import can be known This allows modules to be loaded in parallel, and also allows for things like tree-shaking. The biggest benefits are for web browsers, but all around it's a more constrained way to express dependencies, which allows the bundler/runtime to take more liberties.
- WorldMaker 3y agoCJS does not work in browsers. Bundlers fake it well enough you might not feel that pain regularly, but ESM was designed for use in browsers and CJS wasn't.
- lf-non 3y agoYou could get those benefits through special syntax that chose to not deviate from commonjs semantics. We are in this mess because tc39 explicitly chose to not give a damn about nodejs ecosystem. None of the secondary benefits of ESM to commonjs semantics incompatibility (like recursive imports, top level awaits etc) are IMHO worth the ecosystem disruption.
- jazzypants 3y agoCommonjs is synchronous. If you used it in the browser, it would block the main thread each time you required a module. That's bad.
- lf-non 3y agoESM has dual syntax for static and dynamic imports too. What I am saying is that import Foo from "foo" could be sematically equivalent to const Foo = require("foo") and const Foo = await import("foo") could be semantically equivalent to const Foo = await Promise.resolve(() => require("foo")) if tc39 designed ESM import spec with CJS compat in mind. It is fully possible to introduce additional syntax while not breaking the ecosystem.
- WorldMaker 3y agoCJS makes an assumption that all of the main body of a module is synchronous including its imports and that the main body of all of its imports also ran synchronously prior to the main body of that module. A lot of CJS modules are built around side-effects during module loading, built on assumptions from the way that Node especially synchronously loads everything, that break in any attempt to make the process asynchronous. It's not just a matter of syntax sugar, it's a trouble of bad assumptions and presumptions in the CJS format itself that browsers have no way to paper over (but bundlers can fake by putting everything in the same file). Loading a new file is always an asynchronous operation in a browser. CJS has never supported that. Those problems were known at the time when Node picked CJS. (AMD was the competing format that worked in browsers. AMD had its own problems and was a pain to work in without tools like Typescript, but it was compatible with browsers. CJS never was. ESM imports are backward compatible with AMD imports but because AMD is mostly a dead format in 2023 no browser today actually implements the shims to support that, but they were on the table for a long time and can still be ponyfilled if anyone is crazy enough to have an AMD codebase in 2023 that didn't switch to a CJS-based hodge podge in Node at some point in the last decade and that they can't all-at-once migrate to ESM. Which in my experience mostly just describes what's left of Esri's over-reliance on Dojo's AMD loader for ArcGIS JS and just about nothing else in the wild in 2023.) This mess is all Node's fault and it should have never picked CJS in the first place, that was always the losing horse. (Hypothetically there might have been a place and time in CJS history to force CJS require() to always return a promise and module.exports to always take a function that returns a promise and that hypothetical version might have been compatible enough to import directly from ESM. Nobody actually wanted that hypothetical "ACJS" so it never existed. ACJS could have at least met browsers half-way and might have made the transition less overall painful.)