the definition of “module” is definitely a problem. In webpack, and in node, a module is a file. As in , module.exports also has a property module.id, which is just the filename. In ESM, the definition is a little blurry. I remember seeing anders heljsberg complain about how they defined some syntax but gave no guidance on implementation. I also always get confused about what defines a module, the importer or the exporter, like the chicken before the egg problem. The answer is that using the export keyword defines the file as module. So, in esm, a module is still a file, not the actual imported identifiers. Small background info, you’ll also see the words specifiers and identifers used when people talk about things using their big brains, identifiers are just js objects and identifers are uri strings. Helpful to know when you’re looking for language related packages or ast tools.
.JavaScript modules - JavaScript | MDN
MDN says “…place [export] in front of any items you want exported out of the module”. So, MDN is defining a module as a file also, not the individual exports. But, like Raanan said “For me a module (in the sense of ES-Modules) is practically any element being exported…” , I totally use and think of the term module like that also, but its actually wrong. It’s infuriating lol.
The whole esm thing has real world consequences too. You may not know this, but when you use proper esm imports, the imported objects become shared across v8 context just like builtin objects, such as Array or Map. That is huge right? It means you can just spam iframes to your BENEFIT now, because chromium will put the child frame in another thread, while sharing the modules across memory. V8 also has a concept virtual threads, that it uses to kind of glue together multithreading and the security model, and using the stupid esm syntax or adding type=“module” to a script plays an enormous role in memory performance. I did some test in a nextjs app where I added a button that spammed a hello world div inside an iframe - so just a simple page that could add a bunch of iframes to a list. If you naively imported this module through next/webpack, spamming 20 of them would increase memory ~ 200mb . If you put it in the public folder and avoided webpack and maintained compliant esm syntax, adding those same 20 iframes only added 1-4mb. All from using 1 or 2 extra keywords.
Hilariously, wasm uses node style naming WebAssembly.Module.exports() - JavaScript | MDN
Also, some people seem to think they’re onto something with esm imports. But, I actually completely disagree. GitHub - google/node-sec-roadmap: Some thoughts on how Node.js might respond to a changing security environment . Spoofing and mitm is how things get done in the real world, using remote urls to import things is, imo, a much larger security risk.