啃先生(MrKenniu) | 文
网站进化成 Web app 呈现以下特点
使用更多 JavaScript
更多的用户界面通过现代浏览器提供服务
页面在提供服务的过程中,尽可能少地刷新整个页面
所以现在的网站有非常多代码在客户端运行!庞大的代码库需要被有序地管理起来,而模块系统「Module system」提供一种能力,将代码库切分成一个个模块「Module」
模块系统的派别们
定义模块及模块依赖的方法有好几种标准
<script>标签「没有使用模块系统」
CommonJS
AMD
ES6 模块系统
还有其他的...
script 标签
这种方式并没有使用任何模块系统
各个模块向全局对象「例如,window 对象」导出一个接口。其他模块通过全局对象访问这个接口。
缺点:
容易引起冲突
需要很注意模块加载的顺序
模块使用者需要分解模块的依赖
在大项目里,需要管理的模块非常多,管理难度很高
CommonJS:同步的 require 方法
这种方式使用同步的 require 方法加载一个依赖的模块,并且返回一个接口。给导出对象「exports」添加属性 或者给 module.exports 赋值,都可以定义模块的导出对象。
这种方式通常被使用服务器端 NodeJS
优点
可以利用服务器度的代码
npm 已经有许多使用这种风格的模块
非常方便易用
缺点
阻塞的加载方式不适用于网络环境,网络请求是异步的
加载多个模块时,没有平行加载
AMD: 异步的 require方法
其他应用于浏览器环境模块系统,不支持同步的 require ,但提供了异步 require 方法:
优点
符合网络环境下的异步请求方式
多个模块可以平行加载
缺点
额外的编码开销。可读性比较差
有点像一种临时方案
实现:RequireJS
ES6 模块系统
ECMAScript 2015「第6版本」,为 JavaScript 提供了一些语言结构,形成另一种模块系统
优点
便于静态分析
面向未来的 ES 标准
缺点
浏览器支持此特性,还需要一些时间
现在还比较少模块是基于这种方式编写的
客观的解决方案
让开发人员选择模块系统,允许现有的代码库运行「即使它们使用了其他的模块系统」。
传输
模块需要从服务器传输到客户端,才能被客户端执行。有两种比较极端的传输方式,这两种方式都被广泛应用,但都不是最佳的
一个模块一次请求
所有的模块都在一次请求
一个模块一次请求
优点:只有需要的模块才会被传输
缺点:过多的请求开销
缺点:请求延迟较大,导致程序开始比较慢
一次请求所有模块
优点:请求开销比较少,延迟较少
缺点:还未使用到的模块,还被下载到客户端了
分片传输
多数场景下,需要一种更灵活的传输方式,它介于以上两种极端情况之间:
当编译所有模块时,将一系列模块分解成一组小的分片「chunk」
相对一次请求所有模块,分片的方式使网络请求变成多个更小,更快的请求。程序启动时,不需要用到的分片,将会在需要时才被加载。
相对于一次请求一个模块,这加快程序的初始化,但仍然可以让你在实际使用时获取更多的代码「减少网络请求开销」。
怎么分片,在哪里分片是由开发者决定的。大代码库通过这种方式可以组织得很合理。
结语
针对以上两大主题,Webpack 支持多种模块系统风格,支持灵活的 chunk 传输「Code Split」。
Webpack 是一个 JS 模块打包工具,可以用它打包 Web 网站的 JS 代码库,也可以用来打包第三方代码库。不像 RequireJs 只支持 AMD,NodeJS 是 CommonJS, SeaJS 只支持 CMD,如今还有 ES6 Module ... Webpack 像是集大成于一身,开发者在此之上灵活根据自己喜好编码。
下一篇文章,总结 Code Split 的用法。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。