打包工具 rollup.js 入门教程

作者: 阮一峰

日期: 2022年5月 5日

rollup.js 是一个 JavaScript 打包工具。本文介绍它的基本用法。

一、简介

打包工具的作用是,将多个 JavaScript 脚本合并成一个脚本,供浏览器使用。

浏览器需要脚本打包,主要原因有三个。

(1)早期的浏览器不支持模块,大型网页项目只能先合并成单一脚本再执行。

(2)Node.js 的模块机制与浏览器不兼容,必须通过打包工具进行兼容处理。

(3)浏览器加载一个大脚本,要比加载多个小脚本,性能更好。

目前,最常用的打包工具是 Webpack。它的功能强大,但是难学难用,一直被人诟病。

rollup.js 的开发本意,是打造一款简单易用的 ES 模块打包工具,不必配置,直接使用。这一点,它确实做到了。

后来经过不断发展,它也可以打包 CommonJS 模块。但是,这时需要经过复杂配置,实际上并没有比 Webpack 简单多少。

因此建议,只把 rollup.js 用于打包 ES 模块,这样才能充分发挥它的优势。下面你会看到,那是多么简单的一件事。

如果你的项目使用 CommonJS 模块,不推荐使用 rollup.js,优势不大。

如果你还不了解 ES 模块与 CommonJS 模块之间的差异,详见 ES6 教程

二、安装

本文采用全局安装 rollup.js。


$ npm install --global rollup

但是,你也可以不安装直接使用,就是把下面所有命令中的rollup,替换成npx rollup(参见《npx 使用教程》)。

第一次使用,可以运行下面的命令,查看一下帮助。


$ rollup --help
# 或者
$ npx rollup --help

三、示例

下面,就用 rollup.js 打包两个简单的脚本:库文件 add.js 和入口脚本 main.js。


// add.js
const PI = 3.14;
const E = 2.718;

export function addPi(x) {
  return x + PI;
}

export function addE(x) {
  return x + E; 
}

上面代码中,模块 add.js 输出了两个工具函数addPi()addE()


// main.js
import { addPi } from './add.js';

console.log(addPi(10));

上面代码中,入口脚本 main.js 加载了 add.js 里面的工具函数addPi()

接着,就用 rollup.js 打包。


$ rollup main.js

打包时只需给出入口脚本 main.js,rollup 会自动把依赖项打包进去。

打包结果默认输出到屏幕。


const PI = 3.14;

function addPi(x) {
  return x + PI;
}

console.log(addPi(10));

可以看到,importexport语句都没了,被换成了原始代码。

另外,函数addE()没有打包进去,因为没有用到它。这种特性叫做摇树(tree-shaking),即打包时自动删除没有用到的代码。

由于上面两点,rollup 输出的代码非常整洁,而且体积小于其他打包工具。

使用参数--file [FILENAME],将打包结果保存到指定文件。


$ rollup main.js --file bundle.js

上面命令将打包结果保存到 bundle.js。

四、使用注意点

(1)如果有多个入口脚本,就依次填写它们的文件名,并使用参数--dir指定输出目录。


$ rollup m1.js m2.js --dir dist

上面命令会在目录dist,打包生成多个文件:m1.js、m2.js、以及它们共同的依赖项(如果有的话)。

(2)参数--format iife,会把打包结果放在一个自动执行函数里面。


$ rollup main.js --format iife

(3)如果希望打包后代码最小化,使用参数--compact


$ rollup main.js --compact

另一种方法是使用专门工具。


$ rollup main.js | uglifyjs --output bundle.js

上面命令分成两步,第一步是 rollup 打包,第二步是 uglifyjs 进行代码最小化,最后写入 bundle.js。

(4)rollup 支持使用配置文件(rollup.config.js),把参数都写在里面,下面是一个例子。


// rollup.config.js
export default {
  input: 'main.js',
  output: {
    file: 'bundle.js',
    format: 'es'
  }
};

参数-c启用配置文件。


$ rollup -c

我不推荐使用配置文件,这样会增加额外的复杂性。默认场景下,命令行参数已经够用了,也更容易阅读。

五、转成 CommonJS 模块

最后,rollup 还支持 ES 模块转成 CommonJS 模块,使用参数--format cjs就可以了。


$ rollup add.js --format cjs

转换后的 CommonJS 模块,代码如下。


'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const PI = 3.14;
const E = 2.718;

function addPi(x) {
  return x + PI;
}

function addE(x) {
  return x + E; 
}

exports.addE = addE;
exports.addPi = addPi;

(完)

留言(18条)

确实很简单,必须试试。

看阮老师的文章就是条理清晰,浅显易懂。

esbuild或swc有可能逐步替代这些打包器吗?

尤大的vite就是用rollup打包的,用vite创建的项目run很快

老师思路真清晰!赞!一下子就入门了!

rollup打包存js组件是不是更有优势,部门有几个组件库项目换rollup打包后小了很多

rollup 看起来好简单,nice

简单易懂

阮老师,你好!

我是一个不搞前后端的技渣,我有一个关于前端分离的新想法:
前端-后端-数据库端 三端分离

我的理由是:
1. 数据库方面的开发工作(各种复杂mapper),感觉挺浪费时间的;
2. mapper这些工作(编写、测试)其实跟后端人员关系不大
3. 后端与数据库端分离后,专门由DBBA(数据业务管理员)这一新角色负责,提升开发效率
4. 分离后,如果数据端能够封装出来良好的接口,与后端甚至前端基于接口对接,开发、测试效率会大大提升


我这两天工作上遇到场景,要调优mapper的sql,只改sql,跟后台业务没任何关系,还要等着统一发版,没有任何必要,单独紧急发版在程序上也不合理。

期待您的回复,我这样的想法是否具备可行性,有没有实现的可行性。

一直在用,gulp + rollup

引用虫的发言:

esbuild或swc有可能逐步替代这些打包器吗?

esbuild 和 swc 都是编译器,跟 webpack,rollup 就不是一个概念的东西,怎么替换?学东西怎么学的这么乱呢...

基于rollup有个microbundle的打包器,支持ts,能直接生成CJS、UMD和ESM模块,用来打包JS库挺方便的

引用Norman的发言:

尤大的vite就是用rollup打包的,用vite创建的项目run很快

但是这前后没有关联啊,dev的冷启动快不关rollup的事

哈哈,竟然一直在输出,阮老师动力好足!

嗯,很浅显易懂,很适合入门,话说vite就是用的rollup吧,配置文件挺类似的

引用虫的发言:

esbuild或swc有可能逐步替代这些打包器吗?

esbuild是比较基础的es打包方案,但是比较偏向底层。有很多打包方案底层参考了esbuild
当我们打包的时候,要考虑的内容其实是比较多的
比如说开发环境的热更新,一些插件接入等等。具体工程而言,对于纯lib你可能会考虑esbuild
但通常工程是不会直接使用esbuild的

为啥我本地始终有个rollup -v 都能打印出v2.21.0版本,项目内安装rollup就直接包node:process 找不到。这是什么原因呢

阮老师,想了解下这个rollup是怎么做esm模块合并的,它是怎么做到把三个文件合并成一个的;一直没找到原理说明


https://rollupjs.org/repl

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接