引见
概览
rollup是一个js打包器,用来将很细碎的js编译打包成大的庞杂的东西,像是一个库或许一个运用。其运用了ES6自带的新规范来花样化和打包js代码,而不是原本的Commonjs或许AMD这类解决方案。ES6模块能够使你轻松的无缝的组合你所喜好库中的自力函数(静态函数)。这使得末了能够完成当地化,rollup如今完成了这些。
启动指南
运用npm install --global rollup
敕令下载装置。rollup既能够经由过程一个设置文件运用敕令行接口来挪用,也能够他自身的Javascript API
运用。运转rollup --help
检察可用的敕令和参数。starter project template
有一些常常使用设置的申明,如果须要更细致的申明,点击user guide
。
敕令
这些名设定你的运用的进口是main.js
,而且愿望这些导入末了打包成一个bundle.js
定名的文件。
浏览器环境
# compile to a <script> containing a self-executing function
# 编译到一个<script>元素包含的自力的函数。
$ rollup main.js --format iife --output bundle.js
Node.js环境
# compile to a CommonJS module
# 变异成一个CommonJS规范的模块
$ rollup main.js --format cjs --output bundle.js
浏览器和node.js兼容的环境
# UMD format requires a bundle name
$ rollup main.js --format umd --name "myBundle" --output bundle.js
为什么云云
把项目分红各个小的部份来开辟软件一般活轻易些。由于常常须要去掉代码不希冀的行动,也能够很大水平上下降解决题目的庞杂水平,而且能够只在项目的第一个位置写一些小的项目而不是 isn't necessarily the answer
。不幸的是,JavaScript自身的言语设想没有这类功用。
过滤树功用(Tree Shaking)
为了能够完成ES6模块功用,rollup会静态地剖析你所引入的模块,然后去掉没有真正用到的部份。这会协助你至引入那些须要的东西,而且削减项目的体积。
比方,如果运用CommonJS.悉数的东西和库都会被导入。
// import the entire utils object with CommonJS
// 运用CommonJS悉数的导入utils
var utils = require( 'utils' );
var query = 'rollup';
// use the ajax method of the utils object
// 仅运用utils中的ajax要领
utils.ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
然则如果运用ES6模块体系。替换悉数引入utils模块,而是仅仅引入我们所须要的ajax
函数。
// import the ajax function with an ES6 import statement
//运用es6语句引入ajax函数
import { ajax } from 'utils';
var query = 'rollup';
// call the ajax function
// 挪用ajax函数
ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
由于rollup只包含最低所需,因而它打包的运用体积更小,更疾速,而且使得运用和库之间解耦更松懈。
由于这类要领是建立在import
和export
语句上,因而其效力极高,运转时自动缩减体积,探测打包文件中不须要的变量。
兼容性 Compatibility
导入CommodJS
rollup 能够经由过程插件导入CommondJS模块。
宣布ES6模块
为了保证你的ES6模块能够立时被CommonJS的东西运用,比方在Node或许webpack中,你能够运用rollup来转化成UMD或许CommonJS花样作风。然后指定编译的版本在一个有mian
属性的package.json
文件中。如果你的package.json文件也有module
域(属性),es6敏感的东西,如rollup以及webpack2将会直接导入ES6模块版本。、
衔接
step-by-step tutorial video series, with accompanying written walkthrough
miscellaneous issues in the
wiki
.
最先之前,你的电脑应当已装置了node.js,因而你能够运用npm,另外你也须要晓得怎样运用敕令行东西。
运用rollup最简朴的要领就是经由过程敕令行接口。如今我们要全局装置rollup,在敕令行输入以下敕令。(稍后我们将进修怎样当地装置到你的项目中,那末你的打包将越发爱便利,临时先不要管这么多)。
npm install rollup --global # or `npm i rollup -g` for short
如今你能够运用rollup
,敕令了。
由于没有通报参数,所以rollup只是打印出运用申明。这根rollup --help
或许rollup -h
的结果是一样的。
如今,来建立一个简朴的项目。
mkdir -p my-rollup-project/src
cd my-rollup-project
起首,我们须要一个进口点entry point
,粘贴下面的代码到main.js
文件中。
// src/main.js
import foo from './foo.js';
export default function () {
console.log(foo);
}
然后在建立一个foo.js
文件,就是我们导入点导入的文件。
// src/foo.js
export default 'hello world!';
如今我们来预备天生一个bundle。
rolup src/main.js --format cjs
--format
选项制订我们要打包成什么花样。在这个例子中是CommonJS(能够在Node.js运转)。由于我们没有制订输出的文件,因而将会打印到敕令行。(规范输出stdout)。
'use strict';
var foo = 'hello world!';
var main = function () {
console.log(foo);
};
module.exports = main;
你能够运用以下要领保留编译出来的bundle。
rollup src/main.js --format cjs --output bundle.js
# or `rollup main.js -f cjs -o bundle.js`
(你也能够运用rollup src/main.js > bundle.js
,然则下面你会邃晓,这类体式格局在你想要天生map文件时缺少天真性。)
运转这个代码
node
> var myBundle = require('./bundle.js');
> myBundle();
'hello world!'
祝愿,你已运用rollup建立了第一个bundle。
运用设置文件
现在为止,都还不错,然则当我们最先增加更多的设置时,这就变成了令人讨厌的在敕令行输入(许多)。为了保留我们自身常常使用的设置,我们能够建立一个设置文件,内里保留我们须要的设置。运用js写设置文件比运用敕令行方便多了。
在根目次建立一个设置文件,定名rollup.config.js
,然后增加以下代码。
//rollup.config.js
export default {
entry:'src/main.js',
format:'cjs',
dest:'bundle.js'//即是--output
}
运用 –config or -c flag:来运用该文件。
rm bundle.js//然后搜检该敕令是不是有效。
rollup -c
你能够运用响应的敕令行敕令来掩盖设置文件中的行动。
rollup -c -o bundle-2.js
(注重:rollup是自身运转设置文件,因而我们能够运用export default
语法。语法没有被bable编译,所以你只能运用当前node版本所支撑的es2015语法。)
固然,如果你喜好你能够制订不必的设置文件。
rollup --config rollup.config.dev.js
rollup --confog rollup.config.prod.js
运转build
许多javaScript项目有一个通例:在敕令行实行npm run build
便可实行建立——不管是什么平台的体系。这个很有效,由于如果有人想对你的项目有所孝敬(即分支之类的),那末他就能够直接去关注源码即可而不必分心去相识用了什么依靠,怎样组合等(云云如许的有,rollup,webpack,gulp或许其他)。他们甚至都不必全局装置,就像我们在进修第一部份所做的那样。
设置你自身的npm run build
是很好且简朴的。
建立一个package.json文件
一个package.json文件保留着你的项目的一些主要的信息,包含名字,版本,受权以及以来。(事实上,如果没有package.json文件你不能把你的项目宣布到npm库中——如果你是建立一个运用而非lib库,你仍须要一个package.json文件)。
建立package.json最简朴的要领是在你项目地点的目次的敕令行运转npm init
名来,并跟着提醒一步一步来便可。
翻开你的package.json文件而且在scripts
属性下增加build
进口:
{
...
"scripts":{
"test":"echo \" Error:no test specified\"&& exit 1",
"build":"rollup -c"
}
}
(这个条件是假定你已设置了rollup.config.js
文件在你的项目目次中)
装置当地rollup
到现在为止我们一向运用的是全局装置rollup。运用当地装置rollup是一个更好的挑选,由于任何复制了你项目的人制药运转了npm install
指令,就会获得一个自力兼容(compatible version)版本。
npm install --save-dev rollup #or `npm i -D rollup`
以后注重package.json中的devDependencies
属性将会存在。
{
...,
"devDependencies": {
"rollup": "^0.43.0"
},
...
}
一切你的npm run
将会寻觅当地版原本运转,如果rollup在当地存在的话。
试下下面的敕令。
npm run build
运用npm run dev
完成监控尝尝编译
经由过程装置rollup watch
你能够建立一个敕令,在源码涌现变化是及时编译。
npm install --save-dev rollup-watch
package.json
{
...,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rollup -c",
"dev": "rollup -c -w"
},
...
}
敕令rollup -c -w
(rollup --config --watch
缩写)会以看管形式运转rollup。
最先运用插件
现在为止,我们经由过程进口文件建立了个一简朴的bundle,而且运用相对路径导入了一个模块。跟着须要打包更庞杂的bundle,你常常须要一些天真的特征——导入从npm下载的模块,经由过程babel编译模块,运用json等。
为了应对这些我们运用插件,这些插件会转变rollup在编译时的一些行动。在the rollup wiki中能够找到现在保护的一些插件。
运用插件
在这个教程里我们将运用rollup-plugin-json
插件,它能够使rollup导入json文件里的数据。
装置rollup-plugin-json
作为开辟时依靠(development dependency)。
npm install --save-dev rollup-plugin-json
(我们运用–save-der而不是–save是由于我的代码在运转时不是真正的以来这个插件——只是在我们编译bundle时依靠罢了。)
修正你的src/main.js
文件,让他导入package.json而不是src/foo.js
。
import { version } from '../package.json';
export default function () {
console.log('version ' + version);
}
运转npm run build
,结果回事以下的模样:
'use strict';
var version = "1.0.0";
var main = function () {
console.log('version ' + version);
};
module.exports = main;
(注重:只要我们真正所须要的数据才会被导入——version,其他的name,devDependencies等package.json中的属性将会被疏忽,这就是tree-shaking的作用。)
连系npm库运用rollup
在某种情况下,你的项目须要下载npm的第三方模块到你的node_modules
文件夹中。跟其他的如webpack,Browserfy差别,rollup不晓得out of box
,怎样处置惩罚这些依靠,我们须要增加一些设置。
下载一个the answer
依靠,它导出life,universe,everything题目的答案,
npm install --save the-answer # or `npm i -S the-answer`
注重:此处我们运用的是--save
,因而它被保留到package.json的dependencies
属性中。
如果我们更新src/main.js
文件。。。
import answer from 'the-answer';
export default function () {
console.log('the answer is ' + answer);
}
然后运转rollup
npm run build
我们会看到以下的正告
⚠️ 'the-answer' is imported by src/main.js, but could not be resolved – treating it as an external dependency.
导出来的bundle.js
依然能够在Node.js下运转,由于import
声明被转化成CommonJS作风的require
语句,然则the-answer
没有放到bundle中,因而我们须要一个插件。
rollup-plugin-node-resolve插件
rollup-plugin-node-resolve插件教会rollup怎样去找到扩大的模块。装置。
npm install --save-dev rollup-plugin-node-resolve
这时候运转下npm run build
将不会有毛病抛出,bundle包含导入的组件。
rollup-plugin-commonjs插件
有些库导出的是es6模块,所以你可import
——the-answer
就是这类。但是npm的大多数第三方库是CommonJS作风的模块。在其发作转变之前,我们须要转换CommonJS为ES2015的模块,然后再用rollup处置惩罚。
这正是rollup-plugin-commonjs
的功用地点。
注重rollup-plugin-commonjs
必需在其他的插件转化你的模块之前运转——这是为了防备其他插件打断对CommonJS的探测。
同级依靠peer dependencies
如果你正在建立一个库而且有一个同级依靠(即你的库所须要的依靠而不是开辟依靠),比方React或许Loadash等。如果你像我们上面所讲的那样引入个中,你的bundle将会包含他们悉数。
import answer from 'the-answer';
import _ from 'lodash';
你能够文雅地处置惩罚引入的模块以及bundle。这个李子中,我们把lodash作为模块,然则the-answer不是。
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/main.js',
format: 'cjs',
plugins: [resolve({
// pass custom options to the resolve plugin
customResolveOptions: {
moduleDirectory: 'node_modules'
}
})],
// indicate which modules should be treated as external
external: ['lodash'],
dest: 'bundle.js'
};
如今看下,lodash
会被视作外部,而不是打包到你的lib内里。external
关键字接收一个模块的数组或许一个函数,这个函数的参数是模块的名字,如果这个模块应当不被打包到个中,那末返回true。
export default {
// ...
external: id => /lodash/.test(id)
}
如果你是用babel-plugin-lodash
插件来cherry-pick
lodash模块的话,或许会用这个功用。在这个示例中,Babel将会掩盖你的import语句。
import _merge from 'lodash/merge'
external
数组不会处置惩罚通配符,因而import将仅仅作为不打包罢了。
连系Babel运用rollup
许多开辟者会在他们的项目中运用Babel
,因而他们能够运用一些超前的es6特征,如许能够在浏览器和node环境中运用。
同时运用rollup和Babel的最简朴的要领是运用rollup-plugin-babel
插件。装置:
npm i -D rollup-plugin-babel
在rollup.config.js
中设置。
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
export default {
entry: 'src/main.js',
format: 'cjs',
plugins: [
resolve(),
babel({
exclude: 'node_modules/**' // only transpile our source code
})
],
dest: 'bundle.js'
};
在babel能够真正的编译源码之前,你须要一些设置,建立一个新文件src/.babelrc
:
{
"presets": [
["latest", {
"es2015": {
"modules": false
}
}]
],
"plugins": ["external-helpers"]
}
在这一步有一些东西跟平常不太一样。起首我们设置modules:false
,不然Babel将会在rollup转化前转化我们的模块为CommonJS作风,如许就没法完成rollup的目的(tree shaking)。
其次,我们运用了external-helpers
插件,它使rollup在bundle的头部增加一次’helper’,而不是在每一个运用模块的处所包含他们(这是默许行动)。
第三我们把.babelrc
放在了src文件夹里,而不是项目的跟目次,如果我们售后须要它,这个许可我们有差别的.babelrc
文件对应差别的需求,比方测试。(针对差别的需求设置差别的设置是个好的要领)
如今,在运转rollup之前,我们须要装置latest
预设以及external-helers
插件。
npm i -D babel-preset-latest babel-plugin-external-helpers
如今运转rollup天生不打了,此时能够运用es2015特征了。起首更新下src/main.js
的内容。
import answer from 'the-answer';
export default () => {
console.log(`the answer is ${answer}`);
}
运用npm run build
运转rollup,然后检察bundle。
'use strict';
var index = 42;
var main = (function () {
console.log('the answer is ' + index);
});
映照 Sourcemaps
映照能够经由过程增加--sourcemap
敕令行flag完成,也能够经由过程在设置文件中设置sourceMap:true
属性完成。
问答
什么是‘tree shaking’?
Tree-shaking是活的代码放入——code inclusion,是一种只填加那些运用了的代码的处置惩罚,相似于无用代码剔除,然后进步效力。浏览相识更多:Tree-shaking vs Dead-Code-Elimination
为什么原生的ES2015的模块体系更优于AMD和CommonJS模块规范?
ES2015是官方规范,很快会被浏览器以及Node.js所完成。它们许可静态剖析完成相似tree-shaking如许的结果,而且具有更高等的特征,如轮回援用,及时绑定(live-binding)等。
谁设想了rollup logo?看起来可耐。Julian Lioyd
与其他东西比拟
coming soon…
连系Gulp运用rollup
rollup 返回的是一个Promises,所以gulp能够很轻易的集成。
语法跟设置文件很想,然则属性疏散到两个差别的设置里。
组织bundle,然后导出到目的output。
var gulp = require('gulp')
rollup = require('rollup')
rollupTypescript = require('rollup-plugin-typescript')
;
gulp.task('build',function(){
return rollup.rollup({
entry:"./src/main.js",
plugins:[rollupTypescript()],
}).then(function(bundle){
bundle.write({
format:'umd',
moduleName:'library',
dest:'./dest/library.js',
sourceMap:true
});
})
});