原文链接:http://www.2ality.com/2015/12/bundling-modules-future.html
这篇博客文章探讨的是模块打包是如何被 HTTP/2 和 原生模块这两个新技术所影响。
打包模块就是将若干模块文件合并为一个独立文件。这么做有三个原因:
随着 ECMAScript 6 的到来,JavaScript 终于有了内置模块(下面我称他们为 JavaScript 模块)。但现在这个特性却处在一个尴尬的位置:
一方面, ES6 已将它们的语法和大部分的语义完全标准化了。JavaScript 模块已经是编写模块的常用方式,它们的静态架构可以自动过滤掉没有用到的 exports(在 JavaScript 的世界里也被称为 “tree-shaking”)。
另一方面,如何加载 JavaScript 模块正在标准化,然而并没有 JavaScript 引擎原生地支持他们。这意味着,现在,使用 JavaScript 模块的唯一方式是将他们编译成一种非原生格式。常用的解决方案是:browserify、 webpack、 jspm 和 Rollup.
让我们看看下面这两个新技术,以及它们是如何影响 JavaScript 模块打包。
HTTP/2 正在慢慢地被推出。这是影响模块打包的一个主要因素: 使用 HTTP/2,每个请求的开销比 HTTP/1 降低了很多,这意味着如果你用单文件下载代替多文件下载,几乎不会有性能收益。HTTP/2 允许文件更模块化,方便增量更新:使用文件打包,你总是需要下载完整的打包文件。而不打包的话,你只需要下载有变化的部分(因为其他经常使用的部分仍在浏览器缓存中)。
一旦引擎支持了原生 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 的网站尝试下,这是个非常棒的应用场景。
Rebecca Murphey 的文章 Building for HTTP/2(经常讲解使用新版 HTTP 的最佳实践)。
Chap “探索 ES6” 系列的文章 Modules(讲解了 ES6 模块如何工作)。
扫码关注w3ctech微信公众号
共收到0条回复