也是一款 打包器,它可以将我们项目中的细小的模块打包为整块的额代码, 与 类似,但是相比于 webpack,rollup更为小巧,因为 webpack 在配合插件的使用下 可以完成前端过程中绝大多数的开发工作,而 rollup 仅仅是一个 ESmodules 的打包器,并没有其他 额外的功能,比如 webpack 中有的 html 热替换,在rollup中就没有这个功能,rollup 的诞生并不是与 webpack 进行竞争,它只是为了提供一个高效的 Esmodules 打包器,充分利用 ESmodules 的各项特性的高效打包器,
基本使用
- 新建一个目录 yarn init 初始化 package.json ,新建 src 目录,包含 index.js, message.js ,logger.js 三个文件
// message.js
export default{
hi:"hello my name is xuke"
}
// logger.js
export const log =(msg)=> {
console.log('log')
console.log(msg)
}
export const error =(error)=> {
console.log('error')
console.log(error)
}
//index.js
import {log} from './logger'
import message from './message'
console.log(message.hi)
log('haha')
- 安装 rollup,
yarn add rollup --dev - 通过
yarn rollup ./src/index.js --format iife --file dist/bundle.js对入口文件进行打包./src/index.js 代表入口文件,dist/bundle.js 代表输出文件 - 执行完命令后 我们多出了 dist目录和bundle.js 文件,
// bundle.js
(function () {
'use strict';
const log =(msg)=> {
console.log('log');
console.log(msg);
};
var message = {
hi:"hello my name is xuke"
};
console.log(message.hi);
log('haha');
}());
通过打包对比我们可以看出 rollup 的打包结果比较简洁,没有任何多余的代码,它是将我们代码中的依赖顺序先后拼接到一起,它打包的结果中只会保留用到的部分,对于未引用的部分都没有输出,这是因为 rollup 会自动开启 来优化我们的代码。而 tree shaking 的概念最早也是在 rollup 中提出的。
配置文件
rollup 的配置文件是在 rollup.config.js 中配置的,由于rollup 本身会处理 这个配置文件,所以我们可以使用 ESmodules 语法来写
// rollup.config.js
// rollup 配置文件
export default{
input:'src/index.js',//输入路径
output:{
file:'dist/bundle.js',//输出路径名
format:'iife',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
},//输出路径
}
我们执行 yarn rollup --config 就可以生成打包后的文件了,我们只有带了 --config ,rollup
才会执行我们的配置文件,默认是不会执行我们的配置文件的 ,
rollup 使用插件
插件是 rollup 的唯一的扩展途径,他没有 loder,举例使用 rollup-plugin-json 可以导入 json 的插件
- 安装插件
yarn add rollup-plugin-json --dev - 配置插件
// rollup 配置文件
+ import json from 'rollup-plugin-json'
export default{
input:'src/index.js',//输入路径
output:{
file:'dist/bundle.js',//输出路径名
format:'iife',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
},//输出路径
plugins:[
+ json(),//我们放的是json函数的结果,而不是函数本身
]
}
- 插件的使用,这里我们举例取出 package.json 中的字段
import {log} from './logger'
import message from './message'
+ import {name,version} from '../package.json'
+ console.log(name,version)
console.log(message.hi)
log('haha')
- 重新打包
// bundle.js
(function () {
'use strict';
const log =(msg)=> {
console.log('log');
console.log(msg);
};
var message = {
hi:"hello my name is xuke"
};
+ var name = "rollup";
+ var version = "1.0.0";
console.log(name,version);
console.log(message.hi);
log('haha');
}());
我们观察到 bundle.js 中我们引入的package.json 中的字段已经被打包进来了,而没有被打包进来的 被我们的 tree shaking 移除掉了
rollup npm模块加载
rollup 默认只能按照文件路径的方式加载本地的模块,而对于 node_modules 中的第三方的模块,它并不能像 webpack 一样通过 模块的名称导入相对应的模块,需要安装插件yarn add --dev rollup-plugin-node-resolve,然后在plugins中使用:
// rollup 配置文件
import json from 'rollup-plugin-json'
+ import resolve from 'rollup-plugin-node-resolve'
export default{
input:'src/index.js',//输入路径
output:{
file:'dist/bundle.js',//输出路径名
format:'iife',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
},//输出路径
plugins:[
json(),//我们放的是json函数的结果,而不是函数本身
+ resolve()
]
}
我们安装一个第三方模块测试,安装 yarn add lodash-es --save,在index中引入
import {log} from './logger'
import message from './message'
import {name,version} from '../package.json'
+ import _ from 'lodash-es'
+ console.log(_.concat([1],[2,3],[4]))
console.log(name,version)
console.log(message.hi)
log('haha')
重新打包 执行 yarn rollup --config,在bundle.js中就会生成我们引入的 lodash
rollup 加载 commonjs 模块
rollup 默认只加载 ESmodules 模块,我们要想加载 commonjs 模块就要
- 安装 rollup-plugin-commonjs
- 配置
// rollup 配置文件
import json from 'rollup-plugin-json'
import resolve from 'rollup-plugin-node-resolve'
+ import commonjs from 'rollup-plugin-commonjs'
export default{
input:'src/index.js',//输入路径
output:{
file:'dist/bundle.js',//输出路径名
format:'iife',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
},//输出路径
plugins:[
json(),//我们放的是json函数的结果,而不是函数本身
resolve(),
+ commonjs()
]
}
- 使用 在src目录下新建一个 common.js 文件
// common.js
module.exports={
name:'xuke'
}
在 index.js 中引入
import {log} from './logger'
import message from './message'
import {name,version} from '../package.json'
import _ from 'lodash-es'
+ import common from './common'
+ console.log(common)
console.log(_.concat([1],[2,3],[4]))
console.log(name,version)
console.log(message.hi)
log('haha')
bundle.js
代码拆分
rollup 的代码拆分 是按需导入的方式
index.js
import('./logger').then(()=>{
console.log("xuke")
})
我们这样按需导入的话,我们的配置文件输出目录不能用 file 表示,要用 dir ,format 格式不能定义为 iife(自执行函数,自执行函数会把所有的模块放到一个文件当中,没有办法实现代码拆分),要用 **amd **或者 commonjs中的其他标准 修改配置文件:webpack.config.js
// rollup 配置文件
export default{
input:'src/index.js',//输入路径
output:{
// file:'dist/bundle.js',//输出路径名
// format:'iife',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
dir:'dist',//输出路径名
format:'amd',//代表输出格式,五种输出格式:amd / es6 / iife / umd / cjs
},//输出路径
}
rollup 的优势和缺点
优点:
- 输出结果更加扁平,执行效率更高,
- 会自动移除未引用的代码(内置了 tree shaking)
- 打包结果的可读性比较好
缺点:
- 加载第三方模块比较复杂
- 模块被打包到一个函数中,不能实现 HMR (html-modules-replace)模块热替换
- 浏览器环境中,代码拆分功能必须依赖 amd 库,
打包器选择
当我们使用第三方插件比较多时,我们选用webpack,当我们写一些自定义插件,库,或者框架的时候(vue、react...),我们使用rollup 作为模块打包器,
rollup 一些问题
为什么ES模块比CommonJS更好?
ES模块是官方标准,也是JavaScript语言明确的发展方向,而CommonJS模块是一种特殊的传统格式,在ES模块被提出之前做为暂时的解决方案。 ES模块允许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能。
什么是 ‘tree-shaking’?
Tree-shaking, 也被称为 "live code inclusion," 它是清除实际上并没有在给定项目中使用的代码的过程,但是它可以更加高效。
我如何在 CommonJS 模块中使用 Rollup ?
Rollup 力图实现 ES 模块的规范,而不一定是 Node.js, npm, require(), 和 CommonJS 的特性。 因此,加载 CommonJS 模块和使用 Node 模块位置解析逻辑都被实现为可选插件,默认情况下不在 Rollup 内核中。 你只需要执行 npm install 安装 CommonJS 和 node-resolve 插件然后使用 rollup.config.js 配置文件启用他们,那你就完成了所有设置。
Rollup 是用来构建库还是应用程序?
Rollup 已被许多主流的 JavaScript 库使用,也可用于构建绝大多数应用程序。但是 Rollup 还不支持一些特定的高级功能,尤其是用在构建一些应用程序的时候,特别是代码拆分和运行时态的动态导入 dynamic imports at runtime. 如果你的项目中更需要这些功能,那使用 Webpack可能更符合你的需求。