4 ms·
> Allow es modules to be require()-ed. It's be synchronous and slow and ideologically impure, but it'll make it so that millions of projects (mostly private!) w
by microflash 2y ago
> Allow es modules to be require()-ed. It's be synchronous and slow and ideologically impure, but it'll make it so that millions of projects (mostly private!) will be able to start adopting es modules without a massive refactor.
This is already available in Node.js 22 [1] with ` --experimental-require-module` flag.
[1]: https://nodejs.org/en/blog/announcements/v22-release-announce#support-requireing-synchronous-esm-graphs https://nodejs.org/en/blog/announcements/v22-release-announc...
- jauntywundrkind 2y agoBefore Node had any/experimental module support (April 2019, https://nodejs.medium.com/announcing-a-new-experimental-modules-1be8d2d6c2ff https://nodejs.medium.com/announcing-a-new-experimental-modu...), I'd been using std-things/esm loader for Node.js, which seemed to have no problem allowing CJS and ESM to interop, require and import each other. In my experience it worked flawlessly. https://github.com/standard-things/esm https://github.com/standard-things/esm It's wild to think about: esm has taken nearly a decade to be feasible for folks to use, without heavy encumbrance; it was the key feature of es-2015/es6! It took many more years for import-maps to become a thing, such that we could start using modules in a modular fashion; we've had to use bundlers/codemods to re-resplve dependencies, unless you've been going to go Deno's original path of just hitting absolute urls wherever they be. There's still no standing proposal for how we get import-maps on service-workers & shared workers; modules still are not a ubiquitous feature of the core web & JavaScript ecosystems. 9 years latter. https://github.com/WICG/import-maps/issues/2 https://github.com/WICG/import-maps/issues/2 It's been hard being a webdevs, when the future remains so partially implemented. The article's exploration of the bomb ecosystem is telling. And is much of the reason I hope JavaScript Registry (jsr) project might succeed. Npm will never escape it's past. CJS is going to be in there for a long time. Being on a registry where everything is esm & typescript, that sounds divine. https://deno.com/blog/jsr-is-not-another-package-manager https://deno.com/blog/jsr-is-not-another-package-manager
- z3t4 2y agoDid anyone actually want ES modules, and are anyone using ES modules in production today? I don't think so except for transpiling languages that compile and bundle the JS. The only argument against lazy loading is that single threaded UI's will freeze for a few ms when the code loads, but if you compare that to the time it takes to fully load a modern website that point is moot.
- apitman 2y agoThere are a few hiccups, but I've found ESM to be a huge win overall. The killer feature for me is the ability to write code that can be imported in a browser without any sort of build step. You don't even need node/npm. Just download the file/directory from somewhere and import. It's perfectly feasible to build a complex browser app with many dependencies using nothing but git submodules. The main thing you're missing out on is the optimizations that come with bundlers. But they should be treated as just that: optimizations. You shouldn't be required to use a bundler just to develop/distribute JS programs.
- jauntywundrkind 2y ago(Most) everyone was already using bundlers at this point. Tree shaking was much easier to do after the dependency graph became computeable. Which it wasn't with CJS; require could happen anywhere with any parameters. And require happening anywhere while being sync was kind of a non-starter. That freeze is amplified by most projects having hundreds of not thousands of requires across it's dependency graph. There's definitely some truth to your gripes. Back in 2015 there was a ton of latent hope http/2 push and ESM would let us get away from bundling & perhaps even needing build steps at all. That hasn't panned out. Indeed, push was removed entirely! https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/vOWBKZGoAQAJ https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYL... Except it's still the core backend for Push API. Alas, fetch, in spite of many years of asking for it, never got the ability to observe a Push request, so devs literally never had a chance to explore the possible content update/content discovery use cases that make so so much sense in Web Push Protocol. Crying waste & shame; Push had promise outside of asset delivery but it never got a chance (except the deeply browser-intermediated Push API). There are a variety of tools & options for bundlers to emit bundled esm. Which would nicely make your bundle usable by multiple different consumers.
- tqwhite 2y agoEXACTLY!!! (Though I'd be happier with importSync() to identify the use of ESM packages.)
- paulddraper 2y agoImplementing it in require() allows a library to migrate from CJS to ESM, without breaking any of its downstream users.
- tqwhite 2y agoThat's fair. I worry a little about revising something this fundamental invisibly but, still, fair point.
- alexose 2y agoThat's awesome! I can't wait to try this. Maybe I'm in the minority, but using NPM packages that have changed over to modules continue to be one of my biggest annoyances in NodeJS: npm install node-fetch const fetch = require('node-fetch'); Error [ERR_REQUIRE_ESM]: require() of ES Module npm install node-fetch@2
- throwitaway1123 2y agoYou might just be using the node-fetch example as a stand-in to make your point about esm/cjs, but the fetch api is built in to Node (since v16.15) and is no longer even considered experimental as of Node 21+. https://nodejs.org/docs/latest-v22.x/api/globals.html#fetch https://nodejs.org/docs/latest-v22.x/api/globals.html#fetch