Rollup 是一个 JavaScript 模块打包器,用来将很细碎的js编译打包成大的复杂的代码。其使用了ES6自带的新标准来格式化和打包js代码,而不是原先的Commonjs或者AMD这类解决方案。
使用npm install --global rollup
或者 yarn global add rollup
命令下载安装,
你可以用他自己的 Javascript API来调用,也可以使用 一个配置文件使用命令行接口。运行rollup --help
查看可用的命令和参数。
-i, --input 要打包的文件(必须)
-o, --output.file 输出的文件 (如果没有这个参数,则直接输出到控制台)
-f, --output.format [es] 输出的文件类型 (amd, cjs, es, iife, umd)
-e, --external 将模块ID的逗号分隔列表排除
-g, --globals 以`module ID:Global` 键值对的形式,用逗号分隔开
任何定义在这里模块ID定义添加到外部依赖
-n, --name 生成UMD模块的名字
-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 包含公共的模块(这个选项是默认添加的)
// 指令
rollup src/main.js -o bundle.js -f cjs
把项目分成各个小的部分来开发软件通常活容易些。因为经常需要去掉代码不期望的行为,也能够很大程度上降低解决问题的复杂程度,而且可以只在项目的第一个位置写一些小的项目而不是 isn't necessarily the answer。不幸的是,JavaScript本身的语言设计没有这类功能。
Tree-shaking是活的代码放入——code inclusion,是一种只填加那些使用了的代码的处理,类似于无用代码剔除,然后提高效率, rollup会静态地分析你所引入的模块,然后去掉没有真正用到的部分。这会帮助你至引入那些需要的东西,并且减少项目的体积。
下面演示几个demo
但是当我们开始添加更多的设置时,这就变成了令人讨厌的在命令行输入(很多)指令。为了保存我们自己常用的设置,我们可以创建一个配置文件,里面保存我们需要的设置。使用js写配置文件比使用命令行方便多了。
Rollup的配置文件是可选的,但是使用配置文件的作用很强大,而且很方便,因此推荐你使用。
配置文件是一个ES6模块,它对外暴露一个对象,这个对象包含了一些Rollup需要的一些选项。通常,我们把这个配置文件叫做rollup.config.js,它通常位于项目的根目录
// rollup.config.js
export default {
// 核心选项
input, // 必须
external,
plugins,
// 额外选项
onwarn,
// danger zone
acorn,
context,
moduleContext,
legacy
output: { // 必须 (如果要输出多个,可以是一个数组)
// 核心选项
file, // 必须
format, // 必须
name,
globals,
// 额外选项
paths,
banner,
footer,
intro,
outro,
sourcemap,
sourcemapFile,
interop,
// 高危选项
exports,
amd,
indent
strict
},
};
你必须使用配置文件才能执行以下操作:
把一个项目打包,然后输出多个文件 使用Rollup插件, 例如 rollup-plugin-node-resolve 和 rollup-plugin-commonjs 。这两个插件可以让你加载Node.js里面的CommonJS模块
在根目录创建一个配置文件,命名rollup.config.js,然后添加如下代码。
// rollup.config.js
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'cjs'
}
};
rm bundle.js //先把bundle.js 删除
rollup -c
// 如果你想使用Rollup的配置文件,记得在命令行里加上--config或者-c
命令rollup -c -w(rollup --config --watch缩写)会以监视模式运行rollup
注意:rollup是自己运行配置文件,因此我们可以使用export default语法。语法没有被bable编译,所以你只能使用当前node版本所支持的es2015语法。)
在这里我们将使用rollup-plugin-json
插件,它能够使rollup导入json文件里的数据。
首先安装依赖
yarn add rollup-plugin-json
接着编写
// // src/main.js
import { version } from './package.json';
export default function () {
console.log('version ' + version);
}
// rollup.config.js
import json from 'rollup-plugin-json';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [ json() ]
};
在某种情况下,你的项目需要下载npm的第三方模块到你的node_modules文件夹中。跟其他的如webpack,Browserfy不同,rollup不知道out of box,怎么处理这些依赖,我们需要添加一些设置。 安装 一个the answer依赖
yarn add the-answer
// main.js
import answer from 'the-answer';
export default function () {
console.log('the answer is ' + answer);
}
然后打包 这时候可能会有一个waring
(!) Unresolved dependencies
https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
the-answer (imported by main.js)
打包后的bundle.js仍然会在 Node.js 中工作,因为import声明转变成了 CommonJS中的 require 语句,但是the-answer不包含在包中。因此,我们需要一个插件。
rollup-plugin-node-resolve
这个 rollup-plugin-node-resolve 插件可以告诉 Rollup 如何查找外部模块。 安装它…
yarn add rollup-plugin-node-resolve
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [ resolve() ]
};
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [
resolve(),
babel({
exclude: 'node_modules/**' // 只编译我们的源代码
})
]
};
在Babel实际编译代码之前,需要进行配置。 创建一个新文件src/.babelrc:
{
"presets": [
["latest", {
"es2015": {
"modules": false
}
}]
],
"plugins": ["external-helpers"]
}
可以看一下打包的结果 bundle.js
-
插件生态相对较弱(对比webpack)
一些常见需求无法满足,比如打包多个依赖库,把公共依赖项提出来(webpack的CommonsChunkPlugin) -
文档相对较少,遇到问题无法快速解决
比如常见错误'foo' is not exported by bar.js (imported by baz.js),Troubleshooting算是FAQ,但没有提供详细可靠的解决方案(即照做了也不一定能解决)
-
webpack模块可读性太低
// 引用模块 var _myModule1 = __webpack_require__(0); var _myModule2 = __webpack_require__(10); var _myModule3 = __webpack_require__(24); // 模块定义 /* 10 */ /***/function (module, exports, __webpack_require__) {...} // 源码 _myModule2.default.xxx()
这种代码读起来相当费劲,先找到_myModule2对应的__webpack_require__id,再找对应的模块定义,最后看该模块exports身上挂了什么东西。模块定义这个部分很讨厌,延长了阅读引用链 当然,一般不需要读bundle,这一点并不致命
-
文件打包出来很大
如上面提到的,这些额外的bundle代码(子模块定义、子模块引用等等)导致文件体积膨胀。因为:- 源码每个独立文件外面都包了一层模块定义
- 模块内对其它模块的引用都插了一条__webpack_require__声明
- __webpack_require__工具函数自身的体积
- 文件体积不但会带来传输负担,还会影响Compile时间,打包方案的bundle size是一项重要指标
-
执行很慢
子模块定义和运行时依赖处理(webpack_require),不仅导致文件体积增大,还会大幅拉低性能