Rollup 打包工具笔记
来源:《Webpack实战:入门、进阶与调优(第2版)》- 居玉皓
目录
- [一、Rollup 简介](#一、Rollup 简介)
- [1.1 与 Webpack 的对比](#1.1 与 Webpack 的对比)
- [1.2 适用场景](#1.2 适用场景)
- 二、基本使用
- [2.1 安装](#2.1 安装)
- [2.2 配置文件](#2.2 配置文件)
- [2.3 项目文件](#2.3 项目文件)
- [2.4 打包命令](#2.4 打包命令)
- [2.5 打包结果](#2.5 打包结果)
- [三、Rollup vs Webpack 打包对比](#三、Rollup vs Webpack 打包对比)
- [3.1 Webpack 打包配置](#3.1 Webpack 打包配置)
- [3.2 Webpack 产出结果](#3.2 Webpack 产出结果)
- [3.3 对比结论](#3.3 对比结论)
- [四、Tree Shaking(去除死代码)](#四、Tree Shaking(去除死代码))
- [4.1 特性说明](#4.1 特性说明)
- [4.2 示例代码](#4.2 示例代码)
- [4.3 Rollup 打包结果](#4.3 Rollup 打包结果)
- [五、输出格式(Output Format)](#五、输出格式(Output Format))
- [5.1 支持的格式](#5.1 支持的格式)
- [5.2 多格式输出](#5.2 多格式输出)
- 六、应用场景
- [6.1 实际应用](#6.1 实际应用)
- [6.2 设计理念](#6.2 设计理念)
- 七、补充知识
- [7.1 常用配置选项](#7.1 常用配置选项)
- [7.2 常用插件](#7.2 常用插件)
- [7.3 命令行选项](#7.3 命令行选项)
- [7.4 项目内安装(推荐)](#7.4 项目内安装(推荐))
- [7.5 适用场景总结](#7.5 适用场景总结)
- 八、总结
一、Rollup 简介
1.1 与 Webpack 的对比
- Webpack 的优势:更全面,基于"一切皆模块"的思想而衍生出丰富的可以满足各种使用场景的 loader 和 plugin
- Rollup 的特点:更像一把手术刀,更专注于 JavaScript 的打包
1.2 适用场景
如果当前的项目需求仅仅是打包 JavaScript,比如一个 JavaScript 库,那么 Rollup 很多时候会是我们的第一选择。
二、基本使用
2.1 安装
与 Webpack 一般装在项目内部不同,Rollup 直接全局安装即可:
bash
(sudo) npm i rollup -g
2.2 配置文件
创建 rollup.config.js 配置文件:
javascript
// rollup.config.js
module.exports = {
input: 'src/app.js',
output: {
file: 'dist/bundle.js',
format: 'cjs',
},
};
2.3 项目文件
javascript
// src/app.js
console.log('My first rollup app.');
2.4 打包命令
bash
rollup -c rollup.config.js
-c 参数是告诉 Rollup 使用该配置文件。
2.5 打包结果
javascript
'use strict';
console.log('My first rollup app.');
可以看到,打包出来的东西很干净,Rollup 并没有添加什么额外的代码(就连第1行的 'use strict' 都可以通过配置 output.strict 去掉)。
三、Rollup vs Webpack 打包对比
3.1 Webpack 打包配置
javascript
// webpack.config.js
module.exports = {
entry: './src/app.js',
output: {
filename: 'bundle.js',
},
mode: 'production',
};
3.2 Webpack 产出结果
javascript
!(function(e) {
var t = {};
function r(n) {
if (t[n]) return t[n].exports;
var o = (t[n] = { i: n, l: !1, exports: {}, });
return e[n].call(o.exports, o, o.exports, r), (o.l = !0), o.exports;
}
// 此处省略了50行Webpack代码
})([
function(e, t) {
console.log('My first rollup app.');
}
]);
可以看到,即便项目本身仅仅有一行代码,Webpack 也需要将自身代码注入进去(大概50行左右)。
3.3 对比结论
显然 Rollup 的产出更符合我们的预期,它不包含无关代码,资源体积更小。
四、Tree Shaking(去除死代码)
4.1 特性说明
- 在前面介绍 Webpack 时已经介绍过去除死代码(tree shaking),而实际上这个特性最开始是由 Rollup 实现的,之后被 Webpack 借鉴了过去
- Rollup 去除死代码也是基于对 ES6 Module 的静态分析,找出没有被引用过的模块,将其从最后生成的 bundle 中排除
4.2 示例代码
javascript
// app.js
import { add } from './util';
console.log(`2 + 3 = ${add(2, 3)}`);
// util.js
export function add(a, b) {
return a + b;
}
export function sub(a, b) {
return a - b;
}
4.3 Rollup 打包结果
javascript
'use strict';
function add(a, b) {
return a + b;
}
console.log(`2 + 3 = ${add(2, 3)}`);
可以看到,util.js 中的 sub 函数没有被引用过,因此也没有出现在最终的 bundle.js 中。与之前一样,输出的内容非常清晰简洁,没有附加代码。
五、输出格式(Output Format)
5.1 支持的格式
Rollup 有一项 Webpack 不具备的特性,即通过配置 output.format,开发者可以选择输出资源的模块形式:
- cjs(CommonJS):Node.js 环境常用
- amd(AMD):RequireJS 等使用
- esm(ES Module):现代浏览器和 Node.js 支持
- iife(立即执行函数):浏览器全局变量
- umd(Universal Module Definition):通用模块定义,同时支持多种环境
- system:SystemJS 模块格式
5.2 多格式输出
这项特性对于打包 JavaScript 库特别有用,因为往往一个库需要支持多种不同的模块形式,而通过 Rollup,用几个命令就可以把一份源代码打包为多份。
示例配置:
javascript
// rollup.config.js
export default [
{
input: 'src/index.js',
output: {
file: 'dist/bundle.cjs.js',
format: 'cjs'
}
},
{
input: 'src/index.js',
output: {
file: 'dist/bundle.esm.js',
format: 'esm'
}
},
{
input: 'src/index.js',
output: {
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary' // UMD 需要指定全局变量名
}
}
];
六、应用场景
6.1 实际应用
实际应用中,Rollup 经常被用于打包一些库或框架(比如 React 和 Vue)。
6.2 设计理念
Rollup 在设计之初就主要偏向于 JavaScript 库的构建,以至于它没有 Webpack 对于应用开发那样强大的支持(各种 loader、plugin、HMR 等)。
七、补充知识
7.1 常用配置选项
javascript
// rollup.config.js
export default {
// 入口文件
input: 'src/index.js',
// 输出配置
output: {
file: 'dist/bundle.js',
format: 'cjs',
name: 'MyLibrary', // 用于 UMD/IIFE 格式的全局变量名
sourcemap: true, // 生成 source map
strict: false, // 是否添加 'use strict'
},
// 外部依赖(不打包进 bundle)
external: ['lodash', 'react'],
// 插件
plugins: [
// 常用插件示例
// resolve(), // 解析 node_modules 中的模块
// commonjs(), // 将 CommonJS 转换为 ES6
// babel(), // 使用 Babel 转译
// terser(), // 代码压缩
],
};
7.2 常用插件
- @rollup/plugin-node-resolve:解析 node_modules 中的模块
- @rollup/plugin-commonjs:将 CommonJS 模块转换为 ES6
- @rollup/plugin-babel:使用 Babel 转译代码
- @rollup/plugin-typescript:支持 TypeScript
- rollup-plugin-terser:代码压缩
- rollup-plugin-postcss:处理 CSS
7.3 命令行选项
bash
# 使用配置文件
rollup -c rollup.config.js
# 监听模式(开发时使用)
rollup -c rollup.config.js --watch
# 指定环境变量
rollup -c rollup.config.js --environment NODE_ENV:production
# 输出到标准输出
rollup -c rollup.config.js --stdout
7.4 项目内安装(推荐)
虽然可以全局安装,但在项目中本地安装更推荐:
bash
# 安装为开发依赖
npm install --save-dev rollup
# 在 package.json 中添加脚本
{
"scripts": {
"build": "rollup -c rollup.config.js"
}
}
7.5 适用场景总结
适合使用 Rollup:
- JavaScript 库/框架的打包
- 需要生成多种模块格式
- 追求更小的打包体积
- 简单的 JavaScript 项目
不适合使用 Rollup:
- 复杂的应用开发(缺少 HMR、丰富的 loader 等)
- 需要处理大量非 JavaScript 资源
- 需要复杂的代码分割策略
八、总结
Rollup 是一个专注于 JavaScript 打包的工具,特别适合用于构建库和框架。它的主要优势包括:
- 输出简洁:不包含额外的运行时代码,打包体积小
- Tree Shaking:原生支持,基于 ES6 Module 静态分析
- 多格式输出:支持多种模块格式,适合库的发布
- 专注性强:专注于 JavaScript 打包,设计简洁
但同时也需要注意,Rollup 在应用开发场景下的支持不如 Webpack 全面,选择时需要根据项目需求进行权衡。