Hacker News new | comments | show | ask | jobs | submit login
Using ES modules natively in Node.js (2ality.com)
62 points by ingve 66 days ago | hide | past | web | 5 comments | favorite



Node having ESM support means libraries can start publishing their code with ESM syntax which means bundlers will be able to perform static analysis better when pruning these modules for the browser.

As a web developer these days I'm bundling my server-side code the same way I bundle my client-side code to make server-side rendering easier (because the client code may depend on webpack loaders or non-standard features like JSX). So I don't think ESM support in Node matters much for code that only runs on the server, but it will certainly help with bundle sizes for code that runs on both.

That said, I don't see ESM in the browser as a realistic option for anything except prototyping. AMD runtimes (e.g. RequireJS) had massive performance problems because of the overhead of loading entire modules individually over the wire and HTTP/2 can only do so much to improve on that. The solution to that was bundling, which created in a single large file instead of lots of smaller ones. The size problem was then solved with code splitting and tree shaking. All of these require a "build" step, which means native ESM support in browsers is irrelevant.

ESM has a lot of potential to standardize module loading and improve tooling for front-end builds and code editors. But ESM support in the browser seems like a red herring, especially if it requires an extensive configuration like RequireJS did (which, ironically, became unmaintainable if you didn't generate it automatically).

(This doesn't even address the main problem with most approaches to ESM in the browser, namely that bare names need to be resolved relative to the current module if you want to benefit from any of the multi-version dependency conflict management JS developers have come to rely on. But considering this problem is already being simply ignored in web standards like custom elements, I guess practicality is not a concern)


I would like to see more of the performance issues addressed by browsers. It seems to me that a lot of what webpack does (and maybe more with direct access to JS engine state) in terms of chunking the dependency graph are absolutely optimizations that browsers could do in static analysis stages in module loading, figuring out what to load immediately in the fast path and what to defer. Those sorts of optimizations may not be there on Day 1 of ESM support in browsers, but they could be eventually addressed.

I think HTTP/2 does help a lot, but it's also hard to tell right now because a lot of our collective development environments don't support HTTP/2 well (partly because of the security requirements). Also HTTP/2 could help with that from the other direction. Instead of a tool like webpack bundling chunks, it could offer the chunks as metadata for use in HTTP/2 Server Push.


> HTTP/2 Server Push

which, by the way, is nowhere near usable right now and has a lot of unanswered questions before becoming useful, let alone reliable.

> It seems to me that a lot of what webpack does (and maybe more with direct access to JS engine state) in terms of chunking the dependency graph are absolutely optimizations that browsers could do in static analysis stages in module loading, figuring out what to load immediately in the fast path and what to defer. Those sorts of optimizations may not be there on Day 1 of ESM support in browsers, but they could be eventually addressed.

Except that only concerns execution, not transfer. The browser can only do this when it's already too late. It needs the server to have shipped all the modules to have a fully module graph to work with. The PRPL answer seems to be to do this in the HTTP server instead.

...which of course means server-side build tools again, even if the PRPL advocates like to handwave them away by expecting the HTTP servers to take care of that.


I tried it out myself. CommonJS (read everything in the wild) exports as default.

That means you can't use the following syntax with (most) existing npm modules:

import * as fs from 'fs';

import { map } from 'lodash';

https://github.com/nodejs/node/pull/14369#issuecomment-32903...


I know styfle is aware, but for others, you can unlock named exports of CJS modules with @std/esm:

https://github.com/standard-things/esm

https://medium.com/web-on-the-edge/es-modules-in-node-today-...




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: