ES modules: A cartoon deep-dive (2018)
hacks.mozilla.org
hacks.mozilla.org
I have noticed more and more libs are exporting ESM, but lord knows when we can stop adding special compiler rules.
Jest tests automatically use the CJS version. Webpack builds use the ESM version. (And all my stuff is in TypeScript, so it needs a build step anyway.)
I know the distinction between unit tests and integration tests doesn't matter to some, but I still see a huge usefulness in distinguishing because unit tests should run in the "inner loop" every time a developer is touching code (so must be fast to avoid sapping productivity) and integration tests can be delayed until the "outer loop" (CI processes and UAT processes) so are allowed to be slower. Booting up a "real" browser is definitely on my slow things list and not something I think belongs in unit tests.
(Tho I still use jest as the test runner.)
I think npm should probably support doing that at install time.
ESM importing CJS works in Node, mostly, now, but it does have quite a bit of runtime overhead and prebaking it would be good. Especially because it is unlikely to ever see a CJS loader in the browser (and that would be awful if it did exist).
This tells node that it needs to load it as a CommonJS package and should work fine with ESM.
There's also creating a require function from `node:module` package[1]
[1]: https://nodejs.org/dist/latest-v18.x/docs/api/module.html#mo...
Meanwhile, import cycles are easy to design around and to fix with a single interstitial module if you need it, and "live value" exporting has never been an impediment to me. You can export objects, and their properties are "live" enough for me.
Outside of one specific problem in browsers, I'm not sure what ES6 is actually supposed to buy me. I'm still trying to figure out how to turn of ts-ls "File is a CommonJS module; it may be converted to ES6" disagnostic.
I've tried using this in the past and it didn't go well, so I suppose support is better these days. I'll give it another shot! Thanks for the tips!
I like ESM being the default for .js (which is what "type": "module" mostly does) in a project and then using .cjs files sparingly when necessary (which seems to be mostly just config files for build-time/dev-time tooling with older CLIs today using deprecated loading APIs). That better reflects which is the "present" of JS rather than its past and no need to worry ever about the .mjs bandaid file extension.
I currently have some very exciting code that dumps constructors to text form and sends them to a worker to run...
Oh do tell more, that sounds devious.
Then I do .join('\r\n') on the mess, turn it into a Blob, and pass the URL of the blob into new Worker().
The code running in the worker is only a few classes so it's not worth the hassle of setting up code-copying workarounds or avoiding modules for that portion of the code.
It'll be nice when I can cut that and have nothing more than a few imports and self.onmessage.
Search for "live bindings" if you don't know what difference those make between require and import. Also explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I also see many people complained about the removal of the long-deprecated egrep and fgrep commands.
[jest ESM support] https://github.com/jestjs/jest/issues/9430
[typescript extensions] https://github.com/microsoft/TypeScript/issues/16577
[typescript exports] https://github.com/microsoft/TypeScript/issues/33079
[node.js issues] https://github.com/nodejs/node/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc+label%3Aesm
Only in the from few months ago, tooling support is close enough to make it usable.JS had modules before ESM. ES modules try to solve different problems and offer new solutions with browsers fetching modules themselves, something other module systems don't even do.
Whether a language has modules or not is just a design / ecosystem decision, not a technological one. Swift is a modern language (2014) that doesn't even have modules comparable to what Node.js introduced a 14 years ago. Yet it does little to hamper the quality of apps people are building for the Apple ecosystem.
Microsoft tried to push VBScript as a competitor to JavaScript and ended up copying JavaScript's implementation as JScript. Netscape desperately tried to standardize JavaScript to give it legitimacy (which is how we ended up with ECMAScript, due to the trademark limitations and ECMA being the only standards body that didn't require a lengthy application process).
If you think JavaScript's history is bad, don't look too closely at HTML, a language designed so academics could share information with each other. The Semantic Web pretty much died when search engines became a thing. There's entire offshoots to XHTML that make ES4 look like a success story.
EDIT: It's worth remembering not only what the world looked like that JS was born into but also how the entire Internet evolved since then. Due to JavaScript's unique position, it is heavily invested in backwards compatibility. Except for a number of security-related breaking changes and removals of experimental APIs that never caught on, code written in the early days will still run in modern browsers because it has to. This puts a lot of constraints on its design process and evolution and yet we still see the language undergo massive changes over the past years.