本文介绍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-envscss 和 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-postcssrollup-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-typescriptbabel编译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、esmbrowserslistTS版类库
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``esmpostcss postcss-preset-env cssnano scss本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!