|
> SRI really should be done out of band. Inline SRI would require far to frequent cache invalidation and isn't compatible with package manager workflows where you don't know the exact version of a file you'll depend on. A tool rather should build up an SRI manifest similar to a package lock. This has been discussed several times in module and import map threads. If you are introducing a tool, then you should be bundling your code, not creating more metadata files to load! Bundled code has repeatedly proven to load faster than ESM code using whatever HTTP 3 prefetch mumbo jumbo you throw at it, that no one actually uses in practice anyways. If you have a tool chain, then the answer is easy: don’t delay fetches and create more HTTP requests and roundtrips! As I mentioned in another comment, the sheer ridiculousness of this is demonstrated in the <link rel=“modulepreload”> feature [1], where I kid you not the actual recommendation for having performant dependencies is to litter your HTML file with a link tag for ever JS file that’s imported. We’re right back to where we started with a top level script tag for every script! Argh! But I know, now the recommendation is “oh no silly, your build tool should just create your 100 link tags”. Again, why? If you’re using a build tool a bundled file is way faster than waiting for link tags to get parsed to issue a bunch prefetches and on and on. It’s so frustrating to discuss ESM because the goal posts kerp bouncing between this being an “easy to use feature that removes the need for build tools” only to have every issue with it hand-waived away as trivially solvable by a build tool that ultimately creates a worse end-user load experience than what we already have. > The fact that Node has some JS module / CJS interop issues (and really only when you try to use JS modules from CJS, the other way is fine) is Node's problem, not TC39's. There's really nothing that TC39 could have done here because synchronous require() is the fundamental problem. I think part of the disagreement stems from the fact that you believe my position is that we should have “done nothing” or that the only options were “the system we shipped” or “just do it the node way” or something. That’s not the case at all. I am all for a standard system and I recognize the problems with require(). It is simply the case that a design that took into account the requirements of node could very well have served both systems. These aren’t the only two possible require systems imaginable, but an API that exclusively looks at only one set of constraints, despite billing itself as a general purpose solution, will not generate the best end result. This is shown by the several bandaids that had to be added after the fact to import and could have been avoided if considered beforehand. 1. https://developers.google.com/web/updates/2017/12/moduleprel... |
From my point of view, the goal posts that keep moving are the ones put up by anti-JS-modules folk because they keep comparing unbundled JS modules vs bundled CJS. Unbundled CJS would perform far worse than standard JS modules by all these measures, but somehow gets a pass because it has to be bundled.
What module feature could possibly have solved the waterfall problem? The only options are manifests and bundling. IE, you can't magically tell a browser what it should load without telling it what it should load. modulepreload is essentially a manifest and Web Bundles are bundles, so there are solutions covering the space. Browsers should get behind Web Bundles, asap, since that would also solve many problems for caching, CSS and other assets.
The problem I have with this debate is that JS modules get criticized for being able to work without bundling at all, when that's purely a positive and they still can be bundled for performance.
If you don't like the unbundled workflow, don't use it. It's still useful to have a standardized syntax and semantics, and very useful for those of us who do want to use them unbundled: for simple cases, dev environments, or combined with features like prefetch/preload.