I don't know which is which. I don't care. I don't understand the benefit of a top-level await if I can simply await in a different file. I use Typescript which adds a layer in-between anyway. At work, we use Angular, which (I think) uses both Typescript and maybe esbuild. Or Webpack. Does it compile to ESM, or CJS? Who knows, and it will change in 2 years again anyway.
All of that is something that I consider to be platform-level. It's insane that millions of feature-writing devs are expected to know all these arcana.
> All of that is something that I consider to be platform-level
I agree with this, but the whole point of the blog-post is that the "platform" currently handles this rather poorly.
I have yet to see a frontend-project that was bigger than some three-person-garage-hobby that didn't occasionally run into CJS versus ESM issues. Maybe not something that pops up on the radar of all the devs in the project but at least at the level of folks who take care of the setup and whatnot, it often pops up in rather painful fashion. Case in point; a few angular-versions back, umd-bundles were dropped, which at least for the project I worked on caused me quite a lot of headache as some of our tool-chain (most notably our testing-setup) relied on angular shipping commonJS-compatible modules.
It's currently also a major pain for anyone publishing an npm-package, even if it's primarily intended to be run on node. The kind of incantations one has to do are just insane (especially if you dared to import from node:crypto or want to support more than just the latest lts); I've just stopped bothering after tearing my hair out for a weekend to no avail, even though I really wanted to support ESM as well.
The whole point of this is that ESM was very poorly handled. It's irrelevant to TypeScript, esbuild, Webpack, etc. That tooling handles the complexity for you and sometimes that backfires. I've run into a lot of headaches with the TypeScript compiler.
The fact that you don't know whether your codebase uses TypeScript, esbuild or Webpack is disappointing. It means that those worries have been handled for you and you don't care to learn them, which is never a good stance if you work with this on a daily basis. But I somewhat agree that it should all be vastly simpler.
I also kind of agree with the downvoted/flagged comment re: Golang. The way the JavaScript ecosystem works is highly dependent on the way Node is handled. And Node has, for many years, made ESM needlessly complicated.
> The fact that you don't know whether your codebase uses TypeScript, esbuild or Webpack is disappointing. It means that those worries have been handled for you and you don't care to learn them
En contraire. The problem is that some years ago I did learn the basics, but the ground has shifted underneath my feet multiple times. There's not really an incentive to learn the finer points of ESM-vs-CJS if Typescript hides the input into the system, Angular has its own ideas about modules, uses Webpack or babel internally and then spits out CJS anyway.
The whole JS ecosystem is nice if you edit 10 files by hand, but I just don't know what I should do with the knowledge that I should "require cjs" when I need Typescript for type safety and it'll only let me "import ts" anyway.
Go has the benefit of not having to reach a distributed consensus amongst a variety of individual browser vendors. Try compiling a large Go project with tinygo to get a glimpse of what it's like to have to deal with multiple independent runtimes [1]. If the browser vendors had been able to ship ES4 or ES5 with module support between 1999 and 2009, then Node probably would have implemented it from the very beginning, and there would be no dichotomy between CJS and ESM.
All of that is something that I consider to be platform-level. It's insane that millions of feature-writing devs are expected to know all these arcana.
Then again, it might be fixed™ soon Ⓡ
https://joyeecheung.github.io/blog/2024/03/18/require-esm-in...