本文介绍Rollup
的一些配置及常见插件,最后使用Rollup
实现一个类库和Vue3
的UI组件库。
中文官网
Rollup
是一个JavaScript
的模块化打包工具,通常用它来打包类库
Rollup
主要针对ES Module
进行打包的;Webpack
通常通过各种loader
处理各种各样的文件以及他们的依赖关系;Rollup
更多时候是专注于处理JS
代码(当然也可以处理css
、font
、vue
等文件)Rollup
的配置和理念相对于webpack
来说,更加的简洁和容易理解;webpack
不支持TreeShaking
时, rollup
具备更强的优势;webpack
;而对类库文件进行打包时我们通常使用rollup
相同点
rollup
支持代码分割(分包)esm
、amd
、cjs
、iife
、umd
)javascript// ./src/index.js
// 动态导入的模块会自动分包
import('./logger').then(({ log }) => {
log('code splitting~')
})
npm i -D rollup
与webpack
、babel
不同,rollup
的core
和cli
在同一个包中
配置文件 rollup.config.js
npx rollup --config rollup.config.js
# 使用默认配置文件
支持所有输出格式
javascript// ./rollup.config.js
// 所有 Rollup 支持的格式
const formats = ['es', 'amd', 'cjs', 'iife', 'umd', 'system']
export default formats.map(format => ({
input: 'src/index.js',
output: {
file: `dist/bundle.${format}.js`,
format
}
}))
// 方式二
export default {
input: 'src/index.js',
output: [...]
}
关于rollup
这里有一个极简上手demo
Rollup
自身的功能就只是ES Modules
模块的合并,如果有更高级的要求,例如加载其他类型的资源文件或者支持导入 CommonJS
模块,又或是编译 ES 新特性
,这些额外的需求Rollup
同样支持使用插件去扩展实现。
@rollup/plugin-node-resolve
加载NPM
模块@rollup/plugin-commonjs
加载 CommonJS
模块
umd
出现了require
语句,可能是你没有引用该包@rollup/plugin-json
加载JSON
模块@rollup/plugin-terser
代码压缩rollup-plugin-postcss
处理css
文件
postcss.config.js
文件,这个文件又会根据browserslist
给样式打补丁postcss.config.js
种可以配置cssnano
压缩 css
还可以配置 postcss-preset-env
scss
和 less
有了它你可以忘掉 rollup-plugin-scss
和rollup-plugin-less
了rollup-plugin-vue2
vue-template-compiler
vue2
文件rollup-plugin-vue
@vue/compile-sfc
vue3
文件sfc文件
要配合 rollup-plugin-styles
或 rollup-plugin-postcss
rollup-plugin-peer-deps-external
处理对等依赖rollup-plugin-styles
处理样式,独立出来或者插入 html某个节点中rollup-plugin-replace
代码动态替换(如 process.env.NODE_ENV
)
webpack.DefinePlugin
我们通常使用babel
将es6+
代码转换成es5
以便能在低版本的浏览器上运行。关于babel
如果你还不太了解,可以看我的另一篇文章 《babel深入浅出》。
@rollup/plugin-babel
用于rollup
和babel
之间的无缝集成
为什要使用
@rollup/plugin-babel
?
我们先讨论下不使用翻译es6+
代码的两种方案
- 首先通过
Babel
运行代码,注意排除模块转换器- 或者通过
Rollup
运行代码,然后再用babel
处理代码
以上两种方式都有缺点
- 第一种情况除了配置项复杂外,你最终会在整个代码中重复注入
polyfill
(比如使用了Object.hasOwn
方法的每个文件都会引入一次polyfill
)- 第二种情况转译会更慢,因为对于
Babel
来说转译一个大文件对与转译几个小文件来说需要更多的时间和空间开销- 无论哪种方式,您都必须担心放置中间文件的位置,并且让
sourcemaps
表现得非常痛苦
使用@rollup/plugin-babel
会使整个过程更加容易
javascript// 1. package.json 配置script脚本
// "build": "rimraf lib/* && rollup -c"
// 2. rollup.config.js
const {babel} = require('@rollup/plugin-babel');
const nodeResolve = require('@rollup/plugin-node-resolve');
const commonjs = require("@rollup/plugin-commonjs");
const path = require('path');
const resolve = function(...args) {
return path.resolve(__dirname, ...args);
};
export default [
{
input: resolve('./src/index.js'),
output: {
file: resolve("lib/bundle.umd.js"),
format: 'umd',
name: '$mylib',
},
plugins: [
nodeResolve.default({
browser: true,
}),
commonjs(),
babel({
babelHelpers: 'runtime',
exclude: 'node_modules/**',
}),
],
}
];
// 3. babel.config.js
module.exports = {
"presets": [
["@babel/preset-env", {
"modules": false,
}],
],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: {
version: 3,
proposals: true, // 支持预设
},
useESModules: true,
}
],
]
}
// 4. package.json配置browserslist
// "browserslist": [
// "Android >= 6",
// "ios >= 11",
// ">0.5%"
// ],
rollup
编译TS
有两个方案
rollup-plugin-typescript
babel
编译TS
在研究这两个方案前,我们先了解一下背景
babel
可以将es6
转换成es5
外,typescript
也有这个能力babel
而言,typescript
转es5
灵活性差很多,为不支持插件能力,还有一个硬伤是不支持为es6API提供垫片。更多差异可以看我的另一篇文章《babel如何编译TS》通过实测发现rollup-plugin-typescript
配置该插件虽然能正常打包,但是打包的过程babe.config.js
.browserslist
配置无效,
使用 @babel/preset-typescript
无法生成声明文件,解决方案是 使用 npx tsc
命令 单独生成声明文件 npx tsc --declaration -p ./ -t esnext --emitDeclarationOnly --outDir types
有了上面的基础我们来实现一个类库吧
中文官网给处理 Rollup
构建应用及类库的示例,但是配置太过于简单。
笔者尝试升级了一下类库的配置,支持 babel
和 ts
JS版类库
https://github.com/guojingwen/frondend-project/tree/main/rollup_js_lib
cmd
、umd
、amd
、esm
browserslist
TS版类库
https://github.com/guojingwen/frondend-project/tree/main/rollup_ts_lib
JS
版本所有功能TS
& 自动生成声明文件打包一个Vue3 UI库
https://github.com/guojingwen/frondend-project/tree/main/rollup_ts_vue3_ui_lib
cmd
umd
amd``esm
postcss
postcss-preset-env
cssnano
scss
本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!