持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
前言
大家好,我是陈同学,一枚野生前端开发者,感谢各位的点赞、收藏、评论
Rollup一个用于JavaScript的模块打包器,与webpack齐名并依靠自身差异化的体系设计赢得了许多业界工作者的青睐,同时也在Vite的架构体系中发挥着重要作用
本文阅读成本与收益如下:
阅读耗时:5mins
全文字数:5k+
预期效益
- 入门学习
Rollup基本概念 - 掌握简单的
Rollup打包操作
基本使用
- 新建一个前端工程项目
pnpm init
若无pnpm,先执行命令npm install -g pnpm
- 安装
Rollup依赖
pnpm install rollup
- 新增测试文件
mkdir src
touch src/index.js
touch src/tool.js
touch rollup.config.js
每一个文件内容如下
// src/index.js
import { add } from './tool';
console.log(add(1, 2));
// src/tool.js
export const add = (a, b) => a + b;
export const multi = (a, b) => a * b;
/**
* @type { import('rollup').RollupOptions }
*/
const buildOptions = {
input: ["src/index.js"],
output: {
// 产物输出目录
dir: "dist/es",
// 产物格式
format: "esm",
},
};
export default buildOptions;
- 新增打包命令
在package.json的script中新增语句rollup -c
- 执行命令开始打包
pnpm run build
- 得到打包产物
Tree Shaking 由于ES模块依赖关系是确定的,和运行时状态无关。因此
Rollup可以在编译阶段分析出依赖关系,对AST语法树中没有使用到的节点进行删除
常用配置
- input
定义打包入口文件,可以配置成字符串、数组或者对象,Rollup将根据此参数对应的路径开展打包工作流程
多入口配置:
{
input: ["src/index.js", "src/tool.js"]
}
// 或者
{
input: {
index: "src/index.js",
util: "src/tool.js",
},
}
- output
定义产物输出的目录、格式、是否压缩、静态文件产物命名规则等信息
output的描述对象:
{
output: {
// 产物输出目录
dir: path.resolve(__dirname, 'dist'),
// 以下三个配置项都可以使用这些占位符:
// 1. [name]: 去除文件后缀后的文件名
// 2. [hash]: 根据文件名和文件内容生成的 hash 值
// 3. [format]: 产物模块格式,如 es、cjs
// 4. [extname]: 产物后缀名(带`.`)
// 入口模块的输出文件名
entryFileNames: `[name].js`,
// 非入口模块(如动态 import)的输出文件名
chunkFileNames: 'chunk-[hash].js',
// 静态资源文件输出文件名
assetFileNames: 'assets/[name]-[hash][extname]',
// 产物输出格式,包括`amd`、`cjs`、`es`、`IIFE`、`UMD`、`system`
format: 'cjs',
// 是否生成 sourcemap 文件
sourcemap: true,
// 如果是打包出 IIFE/UMD 格式,需要对外暴露出一个全局变量,通过 name 配置变量名
name: 'DiyBundle',
// 全局变量声明
globals: {
// 项目中可以直接用`$`代替`jquery`
jquery: '$'
}
}
}
多产物配置:
{
output: [
{
dir: "dist/es",
format: "esm",
},
{
dir: "dist/cjs",
format: "cjs",
},
],
}
output属性可为一个数组,数组中每个元素都是一个描述产物的对象,以控制不同产物的输出效果
- external
希望Rollup不打包部分第三方依赖
{
external: ['react', 'react-dom']
}
- plugins
Rollup打包过程中用到的插件,以数组的形式提供
{
plugins: [json()]
}
JavaScript API 方式使用
部分较为复杂的场景下需要基于Rollup定制一些打包过程,仅仅使用配置文件显得不够灵活,这时候需要用到对应JavaScript API来调用Rollup
主要分为rollup.rollup和rollup.watch两个API
rollup.rollup
- 项目根目录下新建文件
build.js
// build.js
const rollup = require("rollup");
// 常用 inputOptions 配置
const inputOptions = {
input: "./src/index.js",
external: [],
plugins:[]
};
const outputOptionsList = [
// 常用 outputOptions 配置
{
dir: 'dist/es',
entryFileNames: `[name].[hash].js`,
chunkFileNames: 'chunk-[hash].js',
assetFileNames: 'assets/[name]-[hash][extname]',
format: 'es',
sourcemap: true,
globals: {
jquery: '_'
}
},
{
dir: 'dist/cjs',
entryFileNames: `[name].[hash].js`,
chunkFileNames: 'chunk-[hash].js',
assetFileNames: 'assets/[name]-[hash][extname]',
format: 'cjs',
sourcemap: true,
globals: {
jquery: '_'
}
},
// 省略其它的输出配置
];
async function build() {
let bundle;
let buildFailed = false;
try {
bundle = await rollup.rollup(inputOptions); // 调用 rollup.rollup 生成 bundle 对象
// 每一次循环体执行中的output均对应一种format的产物数组列表
for (const outputOptions of outputOptionsList) {
const { output } = await bundle.generate(outputOptions); // 拿到 bundle 对象,根据每一份输出配置,调用 generate 和 write 方法分别生成和写入产物
console.log(output);
await bundle.write(outputOptions); // 将产物写入文件系统
}
} catch (error) {
buildFailed = true;
console.error(error);
}
if (bundle) {
// 最后调用 bundle.close 方法结束打包
await bundle.close();
}
process.exit(buildFailed ? 1 : 0);
}
build();
文件保存后在终端执行命令node build.js
以上代码逻辑流程:
- 通过
rollup.rollup方法,传入inputOptions,生成bundle对象 - 调用
bundle对象的generate和write方法,传入outputOptions,分别完成产物和生成和磁盘写入 - 调用
bundle对象的close方法来结束打包
最后可以在dist目录查看打包结果产物
rollup.watch
watch模式下的打包,即每次源文件变动后自动进行重新打包
// watch.js
const rollup = require("rollup");
const watcher = rollup.watch({
input: "./src/index.js",
output: [
{
dir: "dist/es",
format: "esm",
},
{
dir: "dist/cjs",
format: "cjs",
},
],
watch: {
exclude: ["node_modules/**"], // 排除第三方依赖变动监听
include: ["src/**"], // 包括src目录下所有文件的变更监听
},
});
// 监听 watch 各种事件
watcher.on("event", (e) => {
if (e.code === "BUNDLE_END") {
console.log("bundle message:", e);
}
});
watcher.on("restart", () => {
console.log("rebuild...");
});
watcher.on("change", (id) => {
console.log("changed module ID ", id);
});
执行node watch.js开启Rollup的watch打包模式
讲到最后
本节文章我们学习了Rollup的基本配置项的含义以及JavaScript API的使用
实践中,我们能够通过简单的配置完成前端工程项目的简易打包流程
谢谢大家,我们下节再见!!!
感谢各位看到这里,如果你觉得本节内容还不错的话,欢迎各位的点赞、收藏、评论,大家的支持是我做内容的最大动力
本文为作者原创,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利