Search code examples
npmhttp2

HTTP/2: how do I load npm modules in the browser without bundling?


I use Browserify at the moment to bundle my client-side modules into bundles. Each bundle is then loaded as a script tag.

However with HTTP/2, my understanding is that bundling and minification are no longer best practices due to the amount of simultaneous connections available between the client and the server.

So how do I load npm modules in the browser without bundling?

I guess I want to be able to do

var someModule = require('some-module');

And have 'some-module' fetched from the server dynamically.

(I am aware there may be adverse affects on older HTTP/1.1 clients.)


Solution

  • You can't (without hacks and/or rewriting the files), because CJS require is sync. Even if you could, it would still be slow.

    JS thread needs to be suspended waiting for the dependency to be loaded and executed. Without modifying source files doing this would require hacks like sync XHR or document.write, but these won't be able to load dependencies in parallel.

    You could theoretically use some tool to rewrite the files to convert imperative require to callback-driven one (sort-of like conversion of CJS to AMD or ES6 yield compilers for ES5), but that would probably defeat your goal of using npm modules as-is.

    And finally, even if you could load them (or used ES6 modules and travel a bit to the future), it would still be slower than bundling, because the browser doesn't know the full dependency tree, so it has to wait to discover dependencies of dependencies.

    I do recommend webpack chunking (use the analyzer to find chunkable parts of the app) if you'd like to load your app in smaller pieces. It requires using an async require.ensure(cb) though.