什么是Rollup?
前端项目工程化构建工具也发展好几年了,生态演化,慢慢发展出了很多好的构建项目的工具,从最开始的grunt
,gulp
到webpack
,前端的工程化越来越方便,给前端带到了一个美好的时代。
目前,社区中比较火的一个构建工具,是rollup
,用rollup
来打包模块化的JavaScript
代码非常的便利。它使用ES6
中的新的语法标准来打包模块化的代码,将代码拆分成多个小的模块化的代码片段,非常适合JavaScript
类库,插件,和应用的开发。还有一个优点(Tree Shaking
),就是rollup
可以按需打包代码,对于系统中引入了但是没有使用的代码,不会打包到最终文件中。
快速开始
开始之前,需要做一些准备:
安装了
nodejs
和npm
(或者你也可以使用yarn
)了解
ES6
中modules
的概念熟练使用命令行工具
熟悉
gulp
,webpack
(不熟悉也无妨)
首先,需要把rollup
安装到全局空间:
npm install --global rollup (或者使用缩写:npm i -g rollup)
全局安装rollup
之后,就可以使用配置文件的命令行接口或者使用JavaScript API
接口来打包JavaScript
代码。
使用命令行
假设你要打包的入口文件是main.js
,想要把main.js
里引入的所有文件都打包成bundle.js
。
Rollup
提供了多种打包方式,通过format
属性可以设置你想要打包成的代码类型:
amd - 输出成
AMD
模块规则,RequireJS
可以用cjs -
CommonJS
规则,适合Node
,Browserify
,Webpack
等es - 默认值,不改变代码
iife - 输出自执行函数,最适合导入
html
中的script
标签,且代码更小umd - 通用模式,
amd
,cjs
,iife
都能用
根据使用场景,配置不同的format
属性来打包文件。
浏览器使用:
# 编译成一个自执行函数,可以直接在 html 中的 script 标签直接引入
$ rollup main.js --format iife --output bundle.js
Nodejs使用:
# 编译成 CommonJS 模块
$ rollup main.js --format cjs --output bundle.js
浏览器和Nodejs通用:
# UMD 模式需要设置一个大报名
$ rollup main.js --format umd --name "myBundle" --output bundle.js
使用配置文件,来rollup一个项目
开始之前,先在本地创建一个项目,并在根目录通过 npm init
创建一个package.json
文件,构建一个用npm
来管理依赖的项目。
将rollup
安装到项目本地:
npm i --save-dev rollup //--save-dev表示将rollup安装到开发环境依赖中
创建 rollup.config.js
在项目根目录下创建rollup
的配置文件,如下:
// rollup.config.js
export default {
entry: 'src/main.js', //打包入口文件
format: 'iife', //iife模式,适用于浏览器
sourceMap: true, //启用sourcemap
dest: 'dist/bundle.js' //等价于 --output,打包目标文件
};
创建文件src/main.js
,编写入口文件,文件中使用了ES6
中的class
语法。
//src/main.js
class Customer {
constructor(name) {
this.name = name;
}
sayHi() {
console.log(`The name is: ${this.name}`)
console.info(`foo's Uppercase: ${_.upperCase('foo')}`)
}
}
let kevin = new Customer('kevin');
kevin.sayHi();
配置package.json的scripts
{
"scripts": {
"build": "rollup -c" //-c参数全称是 --config,表示使用配置文件
}
}
自定义使用rollup配置文件
上面的build命令:rollup -c
会默认使用项目根目录下的 rollup.config.js
作为项目的rollup
配置文件。如果你想自定义使用其他文件作为配置文件,可以通过参数来指定文件。当对一个应用系统针对不同环境配置多个配置文件的时候特别适用。如下,对开发环境和生产环境分别使用两套配置文件进行项目的配置。
rollup --config rollup.config.dev.js
rollup --config rollup.config.prod.js
//或者,使用简写
rollup -c rollup.config.dev.js
rollup -c rollup.config.prod.js
build项目
配置好上面的内容,就可以开始对 src/main.js
进行打包了。
在命令行中,项目根目录下,执行命令:
npm run build
执行完之后,会看到项目根目录下,生成了一个新的目录:dist
。在 dist
目录下,有两个文件,分别是打包之后的js文件:bundle.js
和 bundle.js
对应的map文件:bundle.js.map
。
打开bundle.js
文件,看到代码如下:
(function () {
'use strict';
class Customer {
constructor(name) {
this.name = name;
}
sayHi() {
console.log(`The name is: ${this.name}`);
}
}
let kevin = new Customer('kevin');
kevin.sayHi();
}());
//# sourceMappingURL=bundle.js.map
可以看到,rollup
将我们的 src/main.js
打包成了一个新的js文件,并给它套上了一个自执行函数,文件最后有对应的map
文件映射声明。
添加babel
在上一步中,可以看到rollup
将代码很好的进行了打包处理。但是,我们在main.js
中用的是ES6
的语法,打包之后还是ES6
的语法,由于目前浏览器还不能很好的兼容ES6
中的语法,所以,要想让我们的代码在浏览器中完美的运行,需要使用babel
将ES6
的语法转换成ES5
的语法。
为了能很好的创建大型应用,拓展第三方插件等,rollup
提供了对第三方插件的支持,在配置文件中添加plugins
来实现插件的引入。
要添加babel
,需要引入插件 rollup-plugin-babel
,使用npm来安装:
npm i -D rollup-plugin-babel --save-dev
除了babel
插件,还需要安装ES6的语法插件 babel-preset-es2015-rollup
:
npm i -D babel-preset-es2015-rollup --save-dev
在项目的根目录下创建babe的配置文件 .babelrc
:
//.babelrc
{
"presets": [
["latest", {
"es2015": {
"modules": false
}
}]
],
"plugins": ["external-helpers"]
}
准备好上述内容,就查最后一步,引入babel
转换器了。修改rollup
的配置文件如下:
import babel from 'rollup-plugin-babel';
export default {
entry: 'src/main.js',
format: 'iife',
dest: 'dist/bundle.js',
sourceMap: true,
plugins: [
babel({
exclude: 'node_modules/**'
})
]
}
修改好配置文件之后,执行一次npm run build
,再重新查看dist/bundle.js
:
(function () {
'use strict';
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var Customer = function () {
function Customer(name) {
classCallCheck(this, Customer);
this.name = name;
}
createClass(Customer, [{
key: 'sayHi',
value: function sayHi() {
console.log('The name is: ' + this.name);
}
}]);
return Customer;
}();
var kevin = new Customer('kevin');
kevin.sayHi();
}());
//# sourceMappingURL=bundle.js.map
可以看到,bundle.js
中已经是转换成ES5
之后的代码了。
更多的插件
在开发项目的过程中,需要引入一个json
文件,可以引入插件rollup-plugin-json
:
npm i --save-dev rollup-plugin-json
更新rollup
配置文件:
import json from 'rollup-plugin-json';
//更新`plugins`属性
plugins: [
babel({
exclude: 'node_modules/**'
}),
json()
]
如果你想要在项目中引入外部模块,你需要rollup-plugin-node-resolve
:
npm install --save-dev rollup-plugin-node-resolve
更新rollup
配置文件:
//引入插件
import resolve from 'rollup-plugin-node-resolve';
//更新`plugins`属性
plugins: [
resolve(),
babel({
exclude: 'node_modules/**'
}),
json()
]
rollup-plugin-commonjs
一些类库导出的是ES6
语法的代码,但是在npm
上大部分模块都是以CommonJS
模式输入模块,所以在rollup
上处理这些模块之前,我们需要将代码从CommonJS
转换成ES6
。
这个时候,就需要安装插件rollup-plugin-commonjs
。
需要注意的是,为了避免这种转换破坏代码结构,rollup-plugin-commonjs
的需要在其他插件之前执行。
rollup-plugin-uglify
要想让打包的文件更小,还需要一个uglify
插件:rollup-plugin-uglify
。
npm install --save-dev rollup-plugin-uglify
更新rollup
配置文件:
//引入插件
import uglify from 'rollup-plugin-uglify';
//更新`plugins`属性
plugins: [
resolve(),
babel({
exclude: 'node_modules/**'
}),
json(),
uglify()
]
本次配置示例代码已放在GitHub上,点我查看
(待续。。。)
//TODO
* 使用rollup引入同级依赖类库
* vue项目开发环境配置
* react开发环境配置
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。