学习下一代的ES6模块化打包工具——Rollup

学习下一代的ES6模块化打包工具——Rollup

z郑雪姣zz郑雪姣z

一、 为什么要用模块化

更好的代码组织方式

如果单个文件越来越大,维护起来出错的几率也会越来越大。模块式的开发,一个文件就是一个模块,控制了文件的粒度,每个模块可以专注于一个功能。

更好的依赖处理

不再需要手动排序多个 <script>标签引用顺序,模块加载器已经帮你做好了。

多人协作互不干扰

和他人合作的时候,经常修改同一个文件?很容易引起冲突?模块化呀。

性能优化

模块化后的代码可以合成一个单一的文件进行部署,减少`HTTP`请求数

... 等等


二、为什么要使用 Rollup 打包工具?

简单做一个测试, 我们准备一个 module.js 文件和 entry.js 文件, 分别使用 Rollup 和 Webpack 打包。

package.json 如下:

module.js 如下:

entry.js 如下:

rollup.config.js 如下:

webpack.config.js 如下:


1. Rollup 可以打出更快更小的包,即使在最坏的情况下,它仍然会小于其他工具产生的捆绑。如图:

Webpack 打包后的 webpack3.0_bundle.js 文件约 3k, 而 Rollup 打包后的 bundle_rollup_iife.js 文件只有1k。

2. 杀手锏——只导出你需要的

Rollup 是第一个提出 Tree Shaking 的打包工具。想对 Tree Shaking 有更全面的了解,推荐阅读 Rich_Harris 的 [Tree-shaking versus dead code elimination](medium.com/@Rich_Harris)。简单来说,Rollup 会静态分析你所引入的模块,去掉没有真正被用到的部分,只引入你需要的部分,减少项目的体积。

通过执行 npm run webpack , 我们得到了 Webpack 打包后的 webpack3.0_bundle.js文件中部分代码截图:

通过执行 npm run rollup -- -c , 我们得到了 Rollup 打包后的 bundle_rollup_iife.js 文件内容:

我们 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 写法如下:

count 被 exports,但是 value 却被锁定了!或者说 count = counter.count, 但 count 的值却没有被改变。

但按照 ES6 的写法:

我们得到了我们想要的结果。ES6 模块导出的是绑定,而不是值。


接下来我们看一下,周期性循环依赖(github.com/rollup/rollup/wiki/Cycles)

关于周期性循环依赖,我们再来看一段代码:


我们经常会听到大家说,不要写循环依赖,那是一种不好的编码方式,会制造很多垃圾。特别是在你写递归函数的时候。大家为什么会这样说?因为对于 AMD 和 CommonJS 来说,编译循环依赖是一个巨大的挑战。但对于 ES6 来说,就容易许多。

Rollup 会将三个文件打包为一个文件。如图:

备注:如果你需要导入 CommonJS, Rollup 可以通过插件 [rollup-plugin-commonjs](rollup/rollup-plugin-commonjs) 导入已存在的 CommonJS 模块。


三、如何使用 Rollup

上文的示例中,已经引入了一些 Rollup 的配置,接下来我们简单介绍一下 Rollup 的使用方法。更多细节,可以参考官方文档。

- [Rollup英文文档](rollup.js)

- [Rollup中文翻译](rollup文档翻译 中文文档 - 前端这两年(2016~) - SegmentFault)

3.1. 安装

你现在可以运行 rollup 命令。来试试!

输出很多相关 Rollup 的命令指引,类似效果 rollup --help 或 rollup -h。

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) 针对浏览器

2)针对 Node.js

3)针对浏览器和Node.js

3.2.2. javascript API —— 将 Rollup 当作一个对象导出

3.2.3. Rollup 与其他构建工具配合使用

链接:github.com/rollup/rollup/wiki/Build-tools


四、 Rollup 插件列表

链接github.com/rollup/rollup/wiki/Plugins


五、参考文章:

Rollup GitHub: github.com/rollup/rollup

Rollup GitHub Wiki: rollup/wiki

Rollup 文档rollupjs.org/


文中内容为学习总结,并非原创。欢迎沟通交流。

还没有评论