Hacker News new | ask | show | jobs
by brundolf 1206 days ago
Right okay, so, let's get our terminology straight real quick: an "import map" is just a piece of configuration that says, "when someone imports from module name X, load it from Y". This would for example let you `import { ... } from 'lodash'` and have it load from `https://unpkg.com/lodash-es@4.17.21`, or whatever else. That's all it does. Everything you're describing above is just about regular "ES module" behavior.

With that out of the way: yes, the lodash case would be pretty egregious if you imported the whole library in one. And most libraries imported this way will not be totally optimal: you'll probably load some code you don't need. But I think lodash is a pretty dramatic outlier; not only is it gigantic, it's exceptionally modular. Compare it to something like React, which is not small, but is nearly a monolith. The same I assume goes for Vue, etc, as well as other kinds of big libraries like GraphQL clients, third-party SDKs, etc. The percentage of code loaded that didn't need to be is, I would guess, usually much much smaller than it is if you're using a single function from lodash

I would add a couple more things:

- Minification is definitely a loss in the naive case, however, that should be easy for a CDN to implement (I think several already do it). I wouldn't be surprised if Deno/Fresh do this automagically too.

- HTTP/2 is optimized to make lots of parallel requests over a single TCP connection, which could conceivably mean a slightly larger total amount of code might load faster as separate modules than a single large bundle would. Of course like you said "depth" is still a limiting factor.

- For extreme cases, dynamic import() is an option in the native ES module system, and can be used to strategically defer module loading

So I don't think it's all that bad, even though like I said above there are tradeoffs. And I'll be curious to see where the industry goes.

PS: It would be good to have the option to bundle with Deno, though. One thing I would be excited to see, personally, is a Deno-ready bundler. One of the main limitations of using Deno right now, if you've got a front-end, is the lack of front-end tooling. You could install Node separately just for tools... but then that's a whole other system dependency, set of concerns, etc. I'd like to be able to do:

  deno run https://deno.land/x/bundler/cli.ts
And have that Just Work™. Maybe it uses WASM modules for speed.

...or maybe this could even be a first-class feature of the `deno` CLI

1 comments

True, I was conflating the idea of having a map of where to find files with the idea of not putting all source in a single file. Though I do still posit that you don't need one if you have the other.

It's a bit like the ancient static vs dynamic linking debate, except in the web case you can't reuse modules that were downloaded by a separate origin, which kinda throws out a lot of the case for dynamic linking. The idea of caching the library files separate from the app files is still potentially valid on a per-origin basis, I suppose.

> HTTP/2 is optimized to make lots of parallel requests over a single TCP connection, which could conceivably mean a slightly larger total amount of code might load faster as separate modules than a single large bundle would

I'd be curious to see this put to the test. It'd require the OS to be able to stream multiple files from memory to the network adapter in parallel at higher bitrate than it could do just one, which is something I'm not sure is possible. Could be, I just don't know. That said, one area it could shine is in letting the browser parse the JS of one request while still downloading the others from the network.

I agree I'd like to see front end bundling treated as more of a first class citizen in the JS backend runtimes. I'm in the Bun camp lately and it is also lacking in that regard. Though as I mentioned, esbuild is great (and Bun interfaces with it faster than Node can!)