rollup文档翻译 中文文档

介绍

概览

rollup是一个js打包器,用来将很细碎的js编译打包成大的复杂的东西,像是一个库或者一个应用。其使用了ES6自带的新标准来格式化和打包js代码,而不是原先的Commonjs或者AMD这类解决方案。ES6模块可以使你轻松的无缝的组合你所喜欢库中的独立函数(静态函数)。这使得最后可以实现本地化,rollup现在实现了这些。java

启动指南

使用npm install --global rollup命令下载安装。rollup既能够经过一个配置文件使用命令行接口来调用,也能够他本身的Javascript API使用。运行rollup --help查看可用的命令和参数。starter project template有一些经常使用设置的说明,若是须要更详细的说明,点击user guidenode

命令

这些名设定你的应用的入口是main.js,而且但愿这些导入最后打包成一个bundle.js命名的文件。webpack

浏览器环境git

# compile to a <script> containing a self-executing function
# 编译到一个<script>元素包含的独立的函数。
$ rollup main.js --format iife --output bundle.js

Node.js环境es6

# compile to a CommonJS module
# 变异成一个CommonJS标准的模块
$ rollup main.js --format cjs --output bundle.js

浏览器和node.js兼容的环境github

# UMD format requires a bundle name
$ rollup main.js --format umd --name "myBundle" --output bundle.js

为什么如此

把项目分红各个小的部分来开发软件一般活容易些。由于常常须要去掉代码不指望的行为,也可以很大程度上下降解决问题的复杂程度,并且能够只在项目的第一个位置写一些小的项目而不是 isn't necessarily the answer。不幸的是,JavaScript自己的语言设计没有这类功能。web

过滤树功能(Tree Shaking)

为了可以实现ES6模块功能,rollup会静态地分析你所引入的模块,而后去掉没有真正用到的部分。这会帮助你至引入那些须要的东西,而且减小项目的体积。ajax

例如,若是使用CommonJS.整个的工具和库都会被导入。typescript

// 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函数。npm

// 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只包含最低所需,所以它打包的应用体积更小,更快速,而且使得应用和库之间解耦更松散。
由于这种方法是创建在importexport语句上,所以其效率极高,运行时自动缩减体积,探测打包文件中不须要的变量。


兼容性 Compatibility

导入CommodJS

rollup 可以经过插件导入CommondJS模块。

发布ES6模块

为了保证你的ES6模块可以立刻被CommonJS的工具使用,例如在Node或者webpack中,你可使用rollup来转化成UMD或者CommonJS格式风格。而后指定编译的版本在一个有mian属性的package.json文件中。若是你的package.json文件也有module域(属性),es6敏感的工具,如rollup以及webpack2将会直接导入ES6模块版本。、

链接


开始以前,你的电脑应该已经安装了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-picklodash模块的话,也许会用这个功能。在这个示例中,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
    });
  })
});
相关文章
相关标签/搜索