一、 为什么要用模块化
更好的代码组织方式
如果单个文件越来越大,维护起来出错的几率也会越来越大。模块式的开发,一个文件就是一个模块,控制了文件的粒度,每个模块可以专注于一个功能。
更好的依赖处理
不再需要手动排序多个 `<script>` 标签引用顺序,模块加载器已经帮你做好了。
多人协作互不干扰
和他人合作的时候,经常修改同一个文件?很容易引起冲突?模块化呀。
性能优化
模块化后的代码可以合成一个单一的文件进行部署,减少`HTTP`请求数
... 等等
二、为什么要使用 Rollup 打包工具?
简单做一个测试, 我们准备一个 `module.js` 文件和 `entry.js` 文件, 分别使用 `Rollup` 和 `Webpack` 打包。
package.json 如下:
&amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-e3a89d79087d078b82062cf229c871c3_b.png" data-rawwidth="640" data-rawheight="451" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic4.zhimg.com/v2-e3a89d79087d078b82062cf229c871c3_r.png"&amp;amp;amp;gt;

module.js 如下:
&amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-f436f1c5e444fc98624dd261736e4015_b.png" data-rawwidth="536" data-rawheight="209" class="origin_image zh-lightbox-thumb" width="536" data-original="https://pic2.zhimg.com/v2-f436f1c5e444fc98624dd261736e4015_r.png"&amp;amp;amp;gt;

entry.js 如下:
&amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-544f52e881f87dd977ae27f24fbdf473_b.png" data-rawwidth="453" data-rawheight="115" class="origin_image zh-lightbox-thumb" width="453" data-original="https://pic4.zhimg.com/v2-544f52e881f87dd977ae27f24fbdf473_r.png"&amp;amp;amp;gt;

rollup.config.js 如下:
&amp;amp;amp;lt;img src="https://pic1.zhimg.com/v2-d9dace4b98e2996bbf7fc07cd84fd8bc_b.png" data-rawwidth="527" data-rawheight="269" class="origin_image zh-lightbox-thumb" width="527" data-original="https://pic1.zhimg.com/v2-d9dace4b98e2996bbf7fc07cd84fd8bc_r.png"&amp;amp;amp;gt;

webpack.config.js 如下:
&amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-10e82b6accc55740f606bb768df1a8e9_b.png" data-rawwidth="440" data-rawheight="204" class="origin_image zh-lightbox-thumb" width="440" data-original="https://pic2.zhimg.com/v2-10e82b6accc55740f606bb768df1a8e9_r.png"&amp;amp;amp;gt;

1. Rollup 可以打出 **更快更小的包**,即使在最坏的情况下,它仍然会小于其他工具产生的捆绑。如图:
&amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-c63bfc8d7fa618170c8298cc97e6e17a_b.png" data-rawwidth="586" data-rawheight="322" class="origin_image zh-lightbox-thumb" width="586" data-original="https://pic3.zhimg.com/v2-c63bfc8d7fa618170c8298cc97e6e17a_r.png"&amp;amp;amp;gt;

Webpack 打包后的 `webpack3.0_bundle.js` 文件约 3k, 而 Rollup 打包后的 `bundle_rollup_iife.js` 文件只有1k。
&amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-ea6eccda5313fbe6cd444705881b86b6_b.png" data-rawwidth="530" data-rawheight="282" class="origin_image zh-lightbox-thumb" width="530" data-original="https://pic3.zhimg.com/v2-ea6eccda5313fbe6cd444705881b86b6_r.png"&amp;amp;amp;gt;

2. **杀手锏——只导出你需要的**
Rollup 是第一个提出 **Tree Shaking** 的打包工具。想对 `Tree Shaking` 有更全面的了解,推荐阅读 `Rich_Harris` 的 [`Tree-shaking versus dead code elimination`](medium.com/@Rich_Harri…)。简单来说,Rollup 会静态分析你所引入的模块,去掉没有真正被用到的部分,只引入你需要的部分,减少项目的体积。
通过执行 `npm run webpack` , 我们得到了 Webpack 打包后的 `webpack3.0_bundle.js` 文件中部分代码截图:
&amp;amp;amp;lt;img src="https://pic1.zhimg.com/v2-d22a4871d9003fd73b36d94ead944a90_b.png" data-rawwidth="640" data-rawheight="319" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic1.zhimg.com/v2-d22a4871d9003fd73b36d94ead944a90_r.png"&amp;amp;amp;gt;

通过执行 `npm run rollup -- -c` , 我们得到了 Rollup 打包后的 `bundle_rollup_iife.js` 文件内容:
&amp;amp;amp;lt;img src="https://pic1.zhimg.com/v2-7ec6f95c36f95c73ab00bf1244065550_b.png" data-rawwidth="428" data-rawheight="218" class="origin_image zh-lightbox-thumb" width="428" data-original="https://pic1.zhimg.com/v2-7ec6f95c36f95c73ab00bf1244065550_r.png"&amp;amp;amp;gt;

我们 Rollup 打包后的文件并没有输出 我们没有调用的函数 `weDontWant` 。
此外, RollupJS 打包会将所有模块打包在一个大的闭包内,从而使代码在浏览器中具有更快的执行速度。
补充说明:Webpack2.0 已经支持 Tree Shaking, 但配置较为复杂。配置方法可以[参考官网](Tree Shaking)
Webpack 3.0 新增 作用域提升 配置。由于作用域提升会移除模块外的函数包装,你可以看到一些小体积的改进。然而,更显著的改进是 Javascript 在浏览器中加载的速度。
3. **Rollup 是基于ES6 实现的代码模块化**
Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是以前的特殊解决方案,如 CommonJS 和 AMD。ES6 模块是 ES6 语法的一部分, ES6 语法是标准化的语言。所以 ES6 模块编写的代码是不会过时的。即便不是这样,也有很多喜欢 ES6 模块的理由。
关于全面的介绍,推荐阅读 [Axel Rauschmayer](Profile): [ECMAScript 6模块:最终语法](ECMAScript 6 modules: the final syntax)
ES6 的部分功能:
- 语法更好
- 模块导出的是绑定,而不是值。
- 支持循环依赖
来看一段代码:
CommonJS 写法如下:
&amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-35a48c18829004837930ff37a34eeac7_b.png" data-rawwidth="640" data-rawheight="370" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic4.zhimg.com/v2-35a48c18829004837930ff37a34eeac7_r.png"&amp;amp;amp;gt;

`count` 被 `exports`,但是 `value` 却被锁定了!或者说 `count = counter.count`, 但 count 的值却没有被改变。
但按照 ES6 的写法:
&amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-af4079c83d6e95225dd880f7324e6b59_b.png" data-rawwidth="606" data-rawheight="301" class="origin_image zh-lightbox-thumb" width="606" data-original="https://pic2.zhimg.com/v2-af4079c83d6e95225dd880f7324e6b59_r.png"&amp;amp;amp;gt;

我们得到了我们想要的结果。ES6 模块导出的是绑定,而不是值。
接下来我们看一下,周期性循环依赖(github.com/rollup/roll…)
关于周期性循环依赖,我们再来看一段代码:
&amp;amp;amp;lt;img src="https://pic1.zhimg.com/v2-c5f11f6fd4effff8a28c80c3e8618824_b.png" data-rawwidth="622" data-rawheight="632" class="origin_image zh-lightbox-thumb" width="622" data-original="https://pic1.zhimg.com/v2-c5f11f6fd4effff8a28c80c3e8618824_r.png"&amp;amp;amp;gt;

我们经常会听到大家说,不要写循环依赖,那是一种不好的编码方式,会制造很多垃圾。特别是在你写递归函数的时候。大家为什么会这样说?因为对于 AMD 和 CommonJS 来说,编译循环依赖是一个巨大的挑战。
但对于 ES6 来说,就容易许多。
但是 Rollup 会将三个文件打包为一个文件。如图:
&amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-83597aaa08b1469c84543df469658acf_b.png" data-rawwidth="640" data-rawheight="280" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic4.zhimg.com/v2-83597aaa08b1469c84543df469658acf_r.png"&amp;amp;amp;gt;

备注:如果你需要导入 CommonJS, Rollup 可以通过插件 [`rollup-plugin-commonjs`](rollup/rollup-plugin-commonjs) 导入已存在的 CommonJS 模块。
三、如何使用 Rollup
上文的示例中,已经引入了一些 Rollup 的配置,接下来我们简单介绍一下 Rollup 的使用方法。更多细节,可以参考官方文档。
- [Rollup英文文档](rollup.js)
- [Rollup中文翻译](rollup文档翻译 中文文档 - 前端这两年(2016~) - SegmentFault)
3.1. 安装
你现在可以运行 `rollup` 命令。来试试!
&amp;amp;amp;lt;img src="https://pic1.zhimg.com/v2-6d9448d30b276d153a57229a61a6633c_b.png" data-rawwidth="546" data-rawheight="51" class="origin_image zh-lightbox-thumb" width="546" data-original="https://pic1.zhimg.com/v2-6d9448d30b276d153a57229a61a6633c_r.png"&amp;amp;amp;gt;

输出很多相关 Rollup 的命令指引,类似效果 `rollup --help` 或 `rollup -h`。
&amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-c4a0a3f84ffab5412ee8fd9502c45e42_b.png" data-rawwidth="462" data-rawheight="57" class="origin_image zh-lightbox-thumb" width="462" data-original="https://pic3.zhimg.com/v2-c4a0a3f84ffab5412ee8fd9502c45e42_r.png"&amp;amp;amp;gt;

3.2. Rollup 使用方法(命令行工具 / javascript API / 其他构建工具当插件引用)
Rollup 提供了多种打包方式,通过 format 属性可以设置你想要打包成的代码类型:
- amd - 输出成AMD模块规则,RequireJS可以用
- cjs - CommonJS规则,适合Node,Browserify,Webpack 等
- es - 默认值,不改变代码
- iife - 输出自执行函数,最适合导入html中的script标签,且代码更小
- umd - 通用模式,amd, cjs, iife都能用
Rollup 官方文档提供了 ES6 模块使用 Rollup 打包之后编译为 AMD, CommonJS, UMD 等运行示例,官网右上角 导航栏里 REL。
3.2.1. 最简单的方式——命令行工具
假设应用程序入口起点的名称为 `main.js`,并且你想要所有 import 的依赖(all imports)都编译到一个名为 `bundle.js` 的单个文件中
1) 针对浏览器
&amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-f55012ba3d12fb850296f241e42748ad_b.png" data-rawwidth="586" data-rawheight="72" class="origin_image zh-lightbox-thumb" width="586" data-original="https://pic2.zhimg.com/v2-f55012ba3d12fb850296f241e42748ad_r.png"&amp;amp;amp;gt;

2)针对 Node.js
&amp;amp;amp;lt;img src="https://pic4.zhimg.com/v2-84d73c37ad280738847629e43807d37b_b.png" data-rawwidth="515" data-rawheight="76" class="origin_image zh-lightbox-thumb" width="515" data-original="https://pic4.zhimg.com/v2-84d73c37ad280738847629e43807d37b_r.png"&amp;amp;amp;gt;

3)针对浏览器和Node.js
&amp;amp;amp;lt;img src="https://pic2.zhimg.com/v2-9f061b04e8f46c9412c8174ea36726c1_b.png" data-rawwidth="617" data-rawheight="74" class="origin_image zh-lightbox-thumb" width="617" data-original="https://pic2.zhimg.com/v2-9f061b04e8f46c9412c8174ea36726c1_r.png"&amp;amp;amp;gt;

3.2.2. javascript API —— 将 Rollup 当作一个对象导出
&amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-6ab2cc941595e0c9aa457a6812585c3a_b.png" data-rawwidth="640" data-rawheight="611" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic3.zhimg.com/v2-6ab2cc941595e0c9aa457a6812585c3a_r.png"&amp;amp;amp;gt;

3.2.3. Rollup 与其他构建工具配合使用
四、 Rollup 插件列表
五、参考文章:
Rollup GitHub: github.com/rollup/roll…
Rollup GitHub Wiki: rollup/wiki
Rollup 文档:rollupjs.org/
&amp;amp;amp;lt;img src="https://pic3.zhimg.com/v2-7bdf37d72dbffd6c30baa5004292f726_b.png" data-rawwidth="60" data-rawheight="55" class="content_image" width="60"&amp;amp;amp;gt;
文中内容为学习总结,并非原创。欢迎沟通交流。