Translator: Atwood. Cai

The original link

This blog post explores how module packaging is being affected by the new technologies of HTTP/2 and native modules.

Why do we pack modules

Packaging a module combines several module files into a single file. There are three reasons to do this:

  1. To facilitate loading all modules, only a few files should be retrieved.
  2. It is slightly more efficient to compress packaged files than separate files.
  3. Exports that are not used are removed during packaging, potentially saving a lot of space.

JavaScript module

With ECMAScript 6, JavaScript finally has built-in modules (I’ll call them JavaScript modules below). But now this feature is in an awkward position:

On the one hand, ES6 has completely standardized their syntax and most of their semantics. JavaScript modules have become a common way of writing modules, and their static architecture automatically filters out exports that are not used (also known as “tree-shaking” in the JavaScript world).

On the other hand, how JavaScript modules are loaded is being standardized, yet no JavaScript engine natively supports them. This means that, right now, the only way to use JavaScript modules is to compile them into a non-native format. Common solutions are browserify, WebPack, JSPM, and Rollup.

Future developments and module packaging

Let’s take a look at these two new technologies and how they affect JavaScript module packaging.

HTTP/2

HTTP/2 is slowly being rolled out. This is a major factor affecting module packaging: with HTTP/2, the overhead per request is much lower than HTTP/1, which means there is little performance gain if you replace multiple file downloads with single file downloads. HTTP/2 allows files to be more modular, facilitating incremental updates: with file packaging, you always need to download the complete package file. Instead of packaging, you only need to download the changed parts (because the other frequently used parts are still in the browser cache).

Native JavaScript modules

Once the engine supports native JavaScript modules, does this affect module packaging? This is especially true for AMD modules that run in native browsers with a custom packaging format (combined with a mini loader). Will native JS modules be different? It seems so. Rollup allows you to package multiple JS modules into a single JS module.

For example, here are two JS modules:

// lib.js
export function foo() {}
export function bar() {}

// main.js
import {foo} from './lib.js';
console.log(foo());
Copy the code

Rollup can package the two JS modules into the following single JS module (note that the unused export bar is removed here) :

function foo() {}

console.log(foo());
Copy the code

First, it doesn’t say that JavaScript modules will work as module packages – to quote Rollup author Rich Harris:

When I started writing Rollup, I thought of it as an experiment, and I wasn’t sure it would work.

The JS module handles imports in a way that helps module packaging: packaging is not a copy of an exports module, to which the module is a read-only view.

You can try it out on Rollup’s website, and it’s a great application scenario.

Further reading

  • Rebecca Murphey’s article Building for HTTP/2(often explains best practices for using new versions of HTTP).

  • Chap Modules, the “Explore ES6” series of articles that explain how the ES6 module works.

  • “Babel and CommonJS modules”