1. 简介
Rollup 是一个 JavaScript 模块打包工具,可以将多个小的代码片段编译为完整的库和应用。与传统的 CommonJS 和 AMD 这一类非标准化的解决方案不同,Rollup 使用的是 ES6 版本 Javascript 中的模块标准。小巧,一个ESM打包器,不支持HMR,利用ESM特性的高效打包器。
2. 上手
新建文件
src/index.js
import { log } from './logger'
import messages from './messages'
const msg = messages.hi
log(msg)
src/messages.js
export default {
hi: 'I am msg'
}
src/logger.js
export const log = msg => {
console.log('打印***msg====> info', msg)
}
export const error = msg => {
console.log('打印***msg====> error', msg)
}
安装rollup yarn add rollup -D 3.14.0
yarn rollup 出现帮助信息
yarn rollup ./src/index.js 打印结果
yarn rollup ./src/index.js --format iife 输出立即执行函数到文件 iife esm cjs amd...
yarn rollup ./src/index.js --format iife --file=dist/bundle.js输出到文件
打包结果如下,默认tree-sharking
配置文件
根目录 rollup.config.js 默认是commonjs ,自身会处理,可以使用esm语法导出个默认对象。不会自己处理 需要type或者mjs结尾。
yarn rollup —config命令
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
}
}
加载资源文件
支持使用插件 是唯一扩展途径,导入json文件的。
安装插件rollup-plugin-json 4.0.0
配置文件
import json from 'rollup-plugin-json'
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [json()]
}
在scr/index.js中使用
import { log } from './logger'
import messages from './messages'
import { version, name } from '../package.json'
const msg = messages.hi
console.log('打印***name,version', name, version)
log(msg)
打包后结果:没有用到的属性不会被打包
加载npm模块
解析 npm 包
默认 rollup 是不解析 npm packages 里面的库的
是只用一个 require 来加载的
```js
var answer = require('the-answer');
如果想也解析 npm packages 里面的库的话 就需要使用 @rollup/plugin-node-resolve 因为 rollup 是只支持 esm 的,但是有的库是使用的 commonJs 规范,所以 rollup 是理解不了的 需要把 commonJs 转换成 ES2015 使用 @rollup/plugin-commonjs 来处理 请注意,大多数情况下 @rollup/plugin-commonjs 应该在转换模块的其他插件之前 - 这是为了防止其他插件进行破坏 CommonJS 检测的更改。 这个规则的一个例外是 Babel 插件,如果你正在使用它,那么把它放在 commonjs 插件之前。
rollup不支持import 引入node_modules下面的模块,需要使用rollup-plugin-node-resolve进行解析。
yarn add rollup-plugin-node-resolve -D 5.2.0
```jsx
import { log } from './logger'
import messages from './messages'
import { version, name } from '../package.json'
import _ from 'lodash-es'
const msg = messages.hi
console.log('打印***name,version', name, version)
log(msg)
console.log('打印***_', _.camelCase('hello'))
rollup.config.js
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'
},
plugins: [json(), resolve()]
}
未使用 lodash-es未打包进去
加载commonJS模块
兼容cjs的导出 rollup-plugin-commonjs 10.1.0
// 新建一个cjs-module.js
module.exports = {
foo: 'foo'
}
// src/index.js
import cjs from './cjs-module'
console.log('打印***cjs', cjs)
rollup.config.js
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()]
}
打包后
代码拆分
动态导入,自动进行分包。
// src/index.js
import('./logger').then(({ log }) => {
log('code,splitting')
})
//rollup.config.js
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: {
dir: 'dist',
format: 'amd'
},
plugins: [json(), resolve(), commonjs()]
}
导出格式不能是iife,会默认放在一起。amd
输出多个文件 dir
输出的文件
多入口打包
公共的模块
// src/logger.js
export const log = msg => {
console.log('打印***msg====> info', msg)
}
export const error = msg => {
console.log('打印***msg====> error', msg)
}
// 多入口 src/index.js
import('./logger').then(({ log }) => {
log('code,splitting')
})
// src/album.js
import fetchApi from './fetch'
import { log } from './logger'
fetchApi('/photo?albumId=1').then(data => {
data.forEach(item => {
log(item)
})
})
// src/fetch.js
export default endpoint => {
return fetch(`https://jsonplaceholder.typicode.com${endpoint}`).then(response => response.json())
}
rollup.config.js
export default {
input: ['src/index.js', 'src/album.js'],
output: {
dir: 'dist',
format: 'amd'
}
}
// ================================== 打包后文件名称
input: {
main: 'src/index.js',
main2: 'src/album.js'
},
dist文件下使用index.js文件,使用require.js进行解析,data-main指定引入文件 ,本地启动服务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script src="<https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.js>" data-main="./index.js"></script>
</html>
Peer dependencies
把对应的库写到 external 内 ,就不会打包到 bundle
external: ['lodash-es']
使用babel
yarn add @babel/core @babel/preset-env @rollup/plugin-babel -D
Babel 插件,放在 commonjs 插件之前
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs
import babel from '@rollup/plugin-babel'
export default {
input: 'src/index.js',
output: {
dir: 'dist',
format: 'cjs'
},
plugins: [
resolve(),
babel({
babelHelpers: 'bundled'
}),
commonjs()
],
}
压缩文件
@rollup/plugin-terser
import terser from '@rollup/plugin-terser'
export default {
input: 'src/index.ts',
output: {
dir: 'dist/',
format: 'esm'
},
plugins: [ terser()]
}
打包ts文件
import typescript from '@rollup/plugin-typescript'
plugins: [typescript({ tsconfig: './tsconfig.json' })
选用原则
- 输出结果更加扁平
- 自动移除未引用代码
- 打包结果依然可读
缺点
- 非esm加载复杂,
- 无法实现hmr
- 浏览器开发依赖requirejs 输出amd,esm可以支持