现今Web网页正逐步向Web App进化,主要体现在:
越来越多依赖JavaScript的使用。
现代浏览器提供了多样化的接口。
更多的局部加载代替全局刷新,甚至单个页面代码量的提升。
因此,客户端将承载大量代码!
大量的底层代码需要被组织。而模块系统则提供了一个可以将底层代码分割成不同模块的方式。
常见的模块系统风格
对于如何定义依赖与引用,存在许多不同的标准:
<script>标签(即不使用模块系统)
CommonJS
AMD及其衍生
ES6模块
其他
<script>标签
下面用一个例子来展示如果你不使用模块系统,你提交的底层代码模块化结构是这样的:
<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>
模块向全局对象(即window对象)暴露一个接口,模块通过全局对象访问依赖的接口。
缺点:
全局空间的污染
需要合理的加载顺序
开发者要解决模块/库的依赖
大型项目中列表冗长且难以管理
CommonJs:同步调用
CommonJs采用require
方法同步调用依赖并返回暴露的接口。一个模块可以通过添加暴露对象的属性或设定module.exports
的值被暴露出来。
require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;
该方法以通过node.js被使用于服务端。
优势
服务端模块可以被复用
有大量现成的模块(如npm)
简单且易于使用
不足
阻塞式并不能很好地适用于互联网,网络环境需要异步调用
无法平行加载多个模块
具体应用
AMD:异步调用
异步模块的定义
在客户端其他同步模块系统有着同样的问题,下面介绍一种异步的版本,包括其如何定义变量与暴露值:
require(["module", "../file"], function(module, file) { /* ... */ });
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
return someExportedValue;
});
优势
满足客户端异步调用风格
可平行加载多个模块
不足
头部声明不利于阅读和编写
看上去像是一种妥协
具体应用
ES6模块
EcmaScript6向JavaScript添加了许多语言结构,因此形成了另一种模块系统。
import "jquery";
export function doStuff() {}
module "localModule" {}
优势
易于静态解析
未来将成为ES标准
不足
还有待浏览器支持
由于比较新,这种方式的实现较少
客观的意见
应然开发者自己选择模块风格,使已存在的代码与库可以正常工作,以简单的方式添加习惯的模块风格。
加载
由于模块需要在客户端执行,因此需要在客户端加载服务端模块。
以下是两种比较极端的模块加载:
一个模块写一个加载
所有模块写在一个加载中
两者都应用广泛,但都有所不足:-
一个模块写一个加载
优势:只有一个模块需要加载
不足:越多模块意味着越多的顶部声明
不足:由于需要较长的加载时间,应用启动较慢
-
所有模块写一个加载
优势:更少的顶部声明,更快的加载
不足:不需要的模块也同时被加载
分块加载
一种更灵活的加载似乎更好。一种介于这两种极端中间的方式对大多数情况来的更好。
当编译所有模块时:把模块的集合拆分成许多更小的chunk(块)。
这能实现更小更快的加载。由模块组成的chunks在初始化的时候并不会被加载。当需要使用模块时,才加载块,这加快了应用加载的速度。
如何分割模块集合取决于开发者。
这让组织大量代码成为可能!
注意:这一想法来源于Google’s GWT。
了解更多关于代码拆分
为何只提到JavaScript
有许多其他资源如样式、图片、字体、HTML 模板也需要处理,为何只提及JavaScript?也还有其他需要编译的资源:coffee script,elm,less,jade,i18n等。
如果把他们都看成chunk(块)事情就变得很简单:
require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");
了解更多关于使用加载
静态解析
当编译所有这些模块时,静态解析会试图找到它的依赖。
通常,只能解析一些简单的格式,但像("./template/" + templateName + ".jade")
又是一种常见的书写格式。
并且多数库都采用不同的写法,有些写法时很奇特的…
策略
一款好的语法分析程序可以是大多数现存代码正常运行。如果开发者风格奇特,它也会试图去找到最合适的解决方法。
译者注:
这个系列会试图将webpack的官方文档都翻译一遍,未翻译的链接,翻译后会改成相应中文翻译页面。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。