w3ctech

[译]JavaScript 模块打包前瞻

原文链接:http://www.2ality.com/2015/12/bundling-modules-future.html

这篇博客文章探讨的是模块打包是如何被 HTTP/2 和 原生模块这两个新技术所影响。

我们为什么要打包模块

打包模块就是将若干模块文件合并为一个独立文件。这么做有三个原因:

  1. 为了方便加载所有的模块,应该只有少量的文件被检索。
  2. 压缩打包后的文件比压缩分开的文件要稍微更高效些。
  3. 打包过程中,没有用到的 exports 会被移除,这可能节省大量的空间。

JavaScript 模块

随着 ECMAScript 6 的到来,JavaScript 终于有了内置模块(下面我称他们为 JavaScript 模块)。但现在这个特性却处在一个尴尬的位置:

一方面, ES6 已将它们的语法和大部分的语义完全标准化了。JavaScript 模块已经是编写模块的常用方式,它们的静态架构可以自动过滤掉没有用到的 exports(在 JavaScript 的世界里也被称为 “tree-shaking”)。

另一方面,如何加载 JavaScript 模块正在标准化,然而并没有 JavaScript 引擎原生地支持他们。这意味着,现在,使用 JavaScript 模块的唯一方式是将他们编译成一种非原生格式。常用的解决方案是:browserify、 webpack、 jspm 和 Rollup.

未来的发展以及模块打包

让我们看看下面这两个新技术,以及它们是如何影响 JavaScript 模块打包。

HTTP/2

HTTP/2 正在慢慢地被推出。这是影响模块打包的一个主要因素: 使用 HTTP/2,每个请求的开销比 HTTP/1 降低了很多,这意味着如果你用单文件下载代替多文件下载,几乎不会有性能收益。HTTP/2 允许文件更模块化,方便增量更新:使用文件打包,你总是需要下载完整的打包文件。而不打包的话,你只需要下载有变化的部分(因为其他经常使用的部分仍在浏览器缓存中)。

原生 JavaScript 模块

一旦引擎支持了原生 JavaScript 模块, 这会对模块打包有影响吗?尤其是对拥有自定义打包格式(与一个迷你加载器结合)的 AMD 模块(运行在原生浏览器中)。原生 JS 模块会有所不同吗?看起来是的。 Rollup 可让你将多个 JS 模块打包为一个独立的 JS 模块。

举个例子,这有两个 JS 模块:

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

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

Rollup 可以把这两个 JS 模块打包到下面这个单个 JS 模块(注意这儿去掉了没用到的 export bar):

function foo() {}

console.log(foo());

首先,它没有说 JavaScript 模块会以模块打包的方式工作 - 引用 Rollup 的作者 Rich Harris 的话:

当我开始编写 Rollup 时,我当它是个实验,并且我不确定会成功。

JS 模块处理 imports 的方式有助于模块打包:打包不是对 exports 的模块的拷贝,对它们来说模块是只读的视图

你可以在 Rollup 的网站尝试下,这是个非常棒的应用场景。

扩展阅读

w3ctech微信

扫码关注w3ctech微信公众号

共收到0条回复