这是我参与更文挑战的第 1 天,活动详情查看: 更文挑战
Lynne,一个能哭爱笑永远少女心的前端开发工程师。身处互联网浪潮之中,热爱生活与技术。
之所以定这个系列目标是因为:
-
对构建工具感兴趣,最近开始从 rollup 入手研究打包工具原理;
-
有个【工具库项目】在做技术选型时定了 rollup 作为打包工具。
总归是要从 0 到 1 一点一点来,正好借此机会开了这个系列一方面督促自己记录心得所学,一方面也希望与大家有交流讨论,基于作者能力有限,希望阅读过的朋友不吝赐教,褒贬皆收~~~
一、初识 rollup
1. 什么是 rollup
选择一个工具,必定是看重它的某个能力,之于我们的开发而言,rollup 是如何脱颖而出的呢?
先不卖关子,就是看准它轻量、快速、体积小,其中不可忽视的就是 tree-shaking!对于 tree-shaking 的详细分析可以看这篇文章 – 无用代码去哪了?项目减重之 rollup 的 Tree-shaking
但还是多说几句废话,再介绍下真正的我眼中的 rollup ~~~
Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。
这是所有打包工具必备能力,那么rollup有什么不同之处和优势呢?又或者熟悉构建工具的同学会说:rollup 已经老生常谈,知道就行了!
但是,从 Webpack2.x 通过插件逐步实现风起于 rollup 的 tree-shaking 功能,到最近炙手可热的 Vite 构建工具也借助了 rollup 的打包能力,众所周知 Vue 和 React 也是使用 rollup 进行打包的,尤其当我们创建函数库、工具库等库的打包时,首选也是 rollup!因此,掌握 rollup 还是非常有必要的!
- rollup 使用 ES6 标准格式打包代码
- 只打包 js ,打包速度快,打包生成的包体积小
- 在处理纯代码上具有算法优势,适用于开发 js 库,当然打包应用开发也可使用
什么时候 rollup 是不推荐使用的呢?
- 需要代码拆分(Code Splitting),rollup 不支持 Code Splitting
- 很多静态资源需要处理,复杂模块化
- 构建的项目需要引入很多 CommonJS 模块的依赖
这时候推荐 Webpack 或者 Vite, 最近 Vite 真是风头正盛,rollup 之后会研究下Vite。
roullup 做了什么?
将消除无用代码后的诸多小块代码编译成为大块复杂可运行在浏览器上的代码。
更详细地来讲就是:
-
rollup 的打包功能意味着 – 我们可以在开发阶段将项目单独拆分成小的模块,以便独立开发,既能减少意料之外的交互,又能降低解决问题的复杂度。
-
静态分析代码中的 import,并删除任何未实际使用的代码,即Tree-shaking。这允许我们在使用依赖模块功能的同时,不会增加额外的依赖从而使项目体积显得臃肿。
借用官网的表述:
因为 Rollup 只引入最基本最精简代码,所以可以生成轻量、快速,以及低复杂度的 library 和应用程序。因为这种基于显式的 import 和 export 语句的方式,它远比「在编译后的输出代码中,简单地运行自动 minifier 检测未使用的变量」更有效。
另外在兼容性方面,rollup 打包输出也做了很好的支持。前端同学可以自行了解 JavaScript 模块 (该链接仅做科普)。
在 rollup 中,可将文件编译为 UMD 或 CommonJS 格式,然后在 package.json 文件的 main 属性中指向当前编译的版本。如果 package.json 也具有 module 字段,像 rollup 和 webpack 2(及以上) 这样的 ES6 感知工具将会直接导入 ES6 模块版本。
二、怎么使用 rollup 打包?
有两种方式,一种是通过可选配置文件和命令行操作,另一种是通过 rollup 的 JS API。
3.1 配置文件 + 命令行
采用命令行打包方式,假设应用程序或 JS 库的入口文件为 main.js,且所有的导入都被编译到一个名为bundle.js的文件中。
浏览器 – rollup main.js --format iife --name "myBundle" --file bundle.js
Node.js – rollup main.js --format cjs --file bundle.js
浏览器 & Node.js – rollup main.js --format cjs --file bundle.js
剩下的关键点就在于 rollup 的配置文件
默认 rollup.config.js,配置文件是一个 ES6 模块,它对外暴露一个对象,这个对象包含了一些Rollup需要的一些选项。
举个栗子:
// rollup.config.js
import json from 'rollup-plugin-json';
export default {
input: 'src/main.js', // 打包入口文件
output: {
file: 'bundle.js', // 打包输出文件
format: 'cjs' // es/umd 也可,需要了解 JS 模块化知识
},
plugins: [ json() ]
};
复制代码
3.2 JavaScript API
rollup.rollup()
返回一个 Promise,它解析了一个 bundle 对象,此对象带有不同的属性及方法,比如 bundle.generate() 和 bundle.write()。
rollup.watch()
当检测到磁盘上单个模块改变,会重新构建你的 bundle,当通过命令行运行 Rollup,并带上 –watch 标记时,此函数会被内部使用。
不详细介绍,原因有二:
- 很少使用…
- 学 API 没什么意思,用到时候再来查
实际使用场景我只见到过一个,参考 rollup 源码中的 debug 文件内容:
// perf-debug.js
loadConfig().then(async config => // 获取收集配置
(await rollup.rollup(config)).generate(
Array.isArray(config.output) ? config.output[0] : config.output
)
);
复制代码
三、rollup 打包原理怎么实现
这是下一篇要讲的,先把 实现打包的 demo 贴上 -> rollup-demo
四、系列规划
rollup 系列主要部分
-
rollup 构建原理及简易流程(下一篇,也有可能会拆分)
-
rollup 的 tree-shaking(参考无用代码去哪了?项目减重之 rollup 的 Tree-shaking)
-
rollup 的插件机制(规划中)
-
rollup 的最佳实践(规划中)
该系列不定期更新,因为会穿插项目需要 做笔记,是的你没你看错,笔记~~~