与webpack作用类似,Rollup更为小巧,它仅仅是一款ESM打包器,并没有其他额外功能,
例如自动化的插件,HMR等在Rollup中不支持
它的诞生并不是要与webpack全民竞争,只是提供一个充分利用ESM各项特性的高效打包器
安装: yarn add rollup —dev(^1.26.3)
使用:yarn rollup ./src/index.js入口文件 —format iife —file dist/bundle.js输出文件
查看rollup命令yarn rollup
# index.js 根文件 // 导入模块成员 import { log } from ‘./logger’ import messages from ‘./messages’ // 使用模块成员 const msg = messages.hi log(msg)
使用打包命令后,会生成 dist/bundle.js 文件
代码相比webpack大量引导代码和模块函数,这里的输出很简略清晰,没有多余代码
输出代码中只会保留用到的部分,对于未引用的部分都没有输出,这是因为rollup默认会自动开启tree shaking,树摇最早在rollup中提出
# bundle.js (function () { ‘use strict’; const log = msg => { console.log(‘————— INFO —————‘); console.log(msg); console.log(‘—————————————‘); }; var messages = { hi: ‘Hey Guys, I am zce~’ }; // 导入模块成员 // 使用模块成员 const msg = messages.hi; log(msg); }());
配置文件
rollup.config.js运行在node环境中,rollup会额外处理这个文件,因此也允许使用ESM
export default { input:’src/index.js’, // 入口文件路径 output:{ // 输出相关配置 file:’dist/bundle.js’ // 输出文件名 format:’iife’ // 输出格式 } }
执行需要通过 yarn rollup —config , 默认情况下它是不会读取配置文件的
指定配置名称来打包文件 yarn rollup —config rollup.production.js
使用插件
rollup的自身功能就是esm模块的合并打包
如果有加载其他类型资源文件,导入Commonjs,编译ES6+新特性等需要使用插件扩展实现
插件是Rollup唯一扩展途径(webpack loader plugins minimizer)
例子
导入json插件,yarn add rollup-plugin-json —dev
# index.js import { log } from ‘./logger’ import messages from ‘./messages’ import { name, version } from ‘../package.json’ // 导入json // 使用模块成员 const msg = messages.hi log(msg) log(name) // 使用json log(version)
配置rollup.config.js
import json from ‘rollup-plugin-json’ export default { input: ‘src/index.js’, output: { file: ‘dist/bundle.js’, format: ‘iife’ }, plugins: [ json() // json函数调用结果放入plugins ] }
查看打包结果
(function () { ‘use strict’; … var name = “03-plugins”; // json会被tree shaking,只显示引用成员 var version = “0.1.0”; log(name); log(version); }());
加载 NPM 模块
rollup默认只能按文件路径的方式加载本地文件模块,对于nodemodules下的第三方模块,并不能像webapck,通过模块名称导入对应模块
yarn add rollup-plugin-node-resolve —dev可以解决rollup使用第三方模块名称导入模块的问题。
import json from ‘rollup-plugin-json’ import resolve from ‘rollup-plugin-node-resolve’ export defalut{ input:’src/index.js’, output:{ file:’dist/bundle.js’, format:’’iife }, plugins:[ json(), resolve() ] }
此时就可以导入 NPM 模块了!
例如
yarn add lodash-es 安装一个模块
# index.js import from ‘lodash-es’ //引入 NPM 模块 _.camelCase(‘hello world’)
注意:使用 lodash-es(lodash esm版本) 而不是 lodash 是因为 rollup 默认只能处理 esm 模块,如果使用普通版本需要做额外处理
加载CommonJS模块
yarn add rollup-plugin-commonjs —dev 为了解决commonjs模块打包问题
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’ }, plugins: [ json(), resolve(), commonjs() ] }
此时,尝试添加一个 commonjs 模块文件
# cjs-module.js module.exports = { foo:’bar’ }
# index.js 入口 import cjs from ‘./cjs-module’ console.log(cjs.foo)
注意:如果改用const cjs = requrie(‘./cjs-module.js’) 引入,需要注意不可以esm和commonjs两个混用,不然require不会被解析
Code Splitting
Dynamic Imports实现按需加载,rollup内部会进行代码拆分
# index.js import(‘./logger’).then(({log})=>{ log(‘code splitting!’) })
此时打包会报错,yarn rollup —config,告诉我们代码拆分打包,format不能使用iife模式,
因为iife会把所有模块放在同一个函数中,相比于webpack并没有引导代码,没法实现代码拆分,因此修改format为amd or commonjs
执行yarn rollup —config —format amd
依然报错,代码分割输出多文件trunk需要修改,file为dir
export default { input: ‘src/index.js’, output: { // file: ‘dist/bundle.js’, // format: ‘iife’ dir: ‘dist’, format: ‘amd’ } }
多入口打包
公共部分也会提取出来作为独立的bundle
export default { // input: [‘src/index.js’, ‘src/album.js’], input: { foo: ‘src/index.js’, bar: ‘src/album.js’ }, output: { dir: ‘dist’, format: ‘amd’ } }
注意:多入口打包内部会自动提前公共模块(内部会代码拆分),就不能用iife,
amd规范无法在浏览器直接引用,通过实现amd标准的库加载(Require.js)
<!DOCTYPE html>
用live server打开这个html
选用原则
优点
- 输出结果更加扁平
- 自动移除未引用代码
- 打包结果依然完全可读
缺点
- 加载非 ESM 的第三方模块比较复杂
- 模块最终被打包到一个函数中,无法实现 HMR
- 浏览器环境中,代码拆分功能依赖 AMD 库
如果我们正在开发应用程序,需要大量引入第三方模块,应用过大还要分包
如果我们开发一个框架或者类库,很少依赖第三方模块,大多数知名框架/库都在使用Rollup作为模块打包
Webpack大而全,Rollup小而美,应用程序用webpack,库/框架Rollup
optimization:{ concatenateModules:true // 抹平了rollup的优势 }