本文简单介绍类库打包工具 rollup 。

Rollup 是一款 JavaScript 模块打包器,可以将多个简单的js代码文件编译成一份复杂的js代码文件,需要注意的是 Rollup 主要用于JavaScript类库的打包,譬如 Vue 框架的源码打包。

使用 Rollup 必要性在于,如果我们开发的是较为复杂的大型项目,那么将项目拆分成小的单独文件来组织代码兴许会更简单,因为这通常会消除无法预知的相互影响(remove unexpected interaction),以及显著降低了所要解决的问题的复杂度(complexity of the problem)。

第一步 安装rollup环境

我们可以通过下面的指令来全局安装 rollup 和一些必要的插件。

1
npm install @babel/preset-env @babel/core rollup rollup-plugin-babel rollup-plugin-serve cross-env -D

rollup 打包工具
@babel/preset-env babel将高级语法转换为高级语法
@babel/core 需要使用 babel核心模块
rollup-plugin-babel 和 babel关联的 rollup插件
rollup-plugin-serve 在本地开启(设置)静态服务
cross-env 在本地设置环境变量等

这里我先新创建 Vue_L文件夹,先执行npm init -y初始化,然后再执行上面的命令行,下面列出安装和执行成功后显示的结果信息。

1
2
3
4
5
6
7
8
+ cross-env@7.0.2
+ rollup-plugin-babel@4.4.0
+ @babel/preset-env@7.9.5
+ @babel/core@7.9.0
+ rollup@2.7.2
+ rollup-plugin-serve@1.0.1
added 158 packages from 93 contributors and audited 2000 packages in 23.326s
found 0 vulnerabilities

第二步 创建配置文件

在根目录中创建rollup.config.js文件,并引入插件模块,并配置入口、出口以及插件等信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import babel from 'rollup-plugin-babel';
import serve from 'rollup-plugin-serve';

export default {
/* 设置打包的入口文件 */
input: "./src/index.js",
/* 输出配置项 */
output: {
/* 配置出口路径 */
file: "dist/umd/xxx.js",
/* 指定打包后全局变量的名字 */
name: "Person",
/* 统一模块规范 */
format: "umd",
/* es6->es5 开启源码调试(显示报错位置) */
sourcemap: true
},
/* 使用插件 */
plugins: [
babel({
exclude: "node_modules/**"
}),
process.env.ENV === 'development' ? serve({
open: true,
/* 默认打开的 HTML 文件路径 */
openPage: "/public/index.html",
port: 3000,
contentBase: ""
}) : null
]
}

第三步 创建其它文件等

在项目根目录中创建 .babelrc 文件,设置文件内容

1
2
3
4
5
{
"presets": [
"@babel/preset-env"
]
}

创建项目所需要的 public 、src 、dist 等文件夹和对应的文件,下面列出文件树结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
wendingding:Vue_L wendingding$ tree -L 2
.
├── dist
│ └── umd
├── node_modules
│ ├── @babel
│ ├── ansi-styles
│ ├── babel-plugin-dynamic-import-node
│ ├── browserslist
│ ├── caniuse-lite
│ ...
│ └── which
├── package-lock.json
├── package.json
├── public
│ └── index.html
├── rollup.config.js
└── src
└── index.js

在 index.html文件中,通过 script文件引入最终打包好的文件.

1
2
3
4
5
6
<script src="/dist/umd/xxx.js"></script>
<script>
// 使用 xxx.js 文件中提供的class
let x = new Person("zs", 18);
console.log(x);
</script>

第四步 执行打包

在 package.json文件中配置scripts项中的build:dev任务和serve任务。

1
2
3
4
5
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:dev": "rollup -c",
"serve": "cross-env ENV=development rollup -c -w",
},

执行指令$ npm run serve即可 (如果只是简单的想要打包,那么执行npm run build:dev指令即可)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* /dist/umd/xxx.js 文件的内容 */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ?
module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Person = factory());
}(this, (function () { 'use strict';

function Person(name, age) {
this.name = name;
this.age = age;
}

return Person;

})));

//# sourceMappingURL=xxx.js.map
1
2
3
4
5
6
rollup v2.7.2
bundles ./src/index.js → dist/umd/xxx.js...
http://localhost:3000 -> /Users/文顶顶/Documents/花田半亩 /Learn/Hall/Vue_L
created dist/umd/xxx.js in 616ms

[2019-08-24 16:35:26] waiting for changes...

-c 等同于--config命令,表示使用 配置文件来执行打包过程。
-w 等同于--watch命令,用于监听源文件是否有改动,如果有改动那么就会重新打包。

这里顺便列出该打包工具的其它可用参数,作为参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-i, --input <filename>      要打包的文件(必须)
-o, --file <output> 输出的文件 (如果没有这个参数,则直接输出到控制台)
-f, --format <format> 输出的文件类型 (amd, cjs, esm, iife, umd)
-e, --external <ids> 将模块ID的逗号分隔列表排除
-g, --globals <pairs> 以`module ID:Global` 键值对的形式,用逗号分隔开
任何定义在这里模块ID定义添加到外部依赖
-n, --name <name> 生成UMD模块的名字
-h, --help 输出 help 信息
-m, --sourcemap 生成 sourcemap (`-m inline` for inline map)
--amd.id AMD模块的ID,默认是个匿名函数
--amd.define 使用Function来代替`define`
--no-strict 在生成的包中省略`"use strict";`
--no-conflict 对于UMD模块来说,给全局变量生成一个无冲突的方法
--intro 在打包好的文件的块的内部(wrapper内部)的最顶部插入一段内容
--outro 在打包好的文件的块的内部(wrapper内部)的最底部插入一段内容
--banner 在打包好的文件的块的外部(wrapper外部)的最顶部插入一段内容
--footer 在打包好的文件的块的外部(wrapper外部)的最底部插入一段内容
--interop 包含公共的模块(这个选项是默认添加的)