I have noticed more and more libs are exporting ESM, but lord knows when we can stop adding special compiler rules.
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...
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.)
(Tho I still use jest as the test runner.)
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.
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.