vite(rollup)
get Started
pnpm i rollup
React
.
├── package.json
├── pnpm-lock.yaml
├── rollup.config.js
└── src
├── index.js
└── util.js
React
// src/index.js
import { add } from "./util";
console.log(add(1, 2));
// src/util.js
export const add = (a, b) => a + b;
export const multi = (a, b) => a * b;
// rollup.config.js
// 以下注释是为了能使用 VSCode 的类型提示
/**
* @type { import('rollup').RollupOptions }
*/
const buildOptions = {
input: ["src/index.js"],
output: {
// 产物输出目录
dir: "dist/es",
// 产物格式
format: "esm",
},
};
export default buildOptions;
JSON
{
// rollup 打包命令,`-c` 表示使用配置文件中的配置
"build": "rollup -c"
}
自动Tree Shaking
配置(input,ouput,exteral)
1.多产物配置
React
// rollup.config.js
/**
* @type { import('rollup').RollupOptions }
*/
const buildOptions = {
input: ["src/index.js"],
// 将 output 改造成一个数组
output: [
{
dir: "dist/es",
format: "esm",
},
{
dir: "dist/cjs",
format: "cjs",
},
],
};
export default buildOptions;
2.多入口配置
React
{
input: ["src/index.js", "src/util.js"]
}
// 或者
{
input: {
index: "src/index.js",
util: "src/util.js",
},
}
如果不同入口对应的打包配置不一样,我们也可以默认导出一个配置数组
,如下所示:
// rollup.config.js
/**
* @type { import('rollup').RollupOptions }
*/
const buildIndexOptions = {
input: ["src/index.js"],
output: [
// 省略 output 配置
],
};
/**
* @type { import('rollup').RollupOptions }
*/
const buildUtilOptions = {
input: ["src/util.js"],
output: [
// 省略 output 配置
],
};
export default [buildIndexOptions, buildUtilOptions];
3. 自定义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: 'MyBundle',
// 全局变量声明
globals: {
// 项目中可以直接用`$`代替`jquery`
jquery: '$'
}
}
关于globals iife和umd格式下,相当于默认iife函数的参数就是$. https://rollupjs.org/configuration-options/#output-globals
4. 依赖 external(搭配globals使用)
对于某些第三方包,有时候我们不想让 Rollup 进行打包,也可以通过 external 进行外部化:
{
external: ['react', 'react-dom']
}
5. 接入插件能力
- rollup本身不支持 input有commonjs规范(主要是第三方包)
pnpm i @rollup/plugin-node-resolve @rollup/plugin-commonjs
// rollup.config.js
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
/**
* @type { import('rollup').RollupOptions }
*/
export default {
input: ["src/index.js"],
output: [
{
dir: "dist/es",
format: "esm",
},
{
dir: "dist/cjs",
format: "cjs",
},
],
// 通过 plugins 参数添加插件
plugins: [resolve(), commonjs()],
};
JavaScript API 方式调用
(rollup,watch)更灵活
rollup
/ 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: {
lodash: '_'
}
}
// 省略其它的输出配置
];
async function build() {
let bundle;
let buildFailed = false;
try {
// 1. 调用 rollup.rollup 生成 bundle 对象
bundle = await rollup.rollup(inputOptions);
for (const outputOptions of outputOptionsList) {
// 2. 拿到 bundle 对象,根据每一份输出配置,调用 generate 和 write 方法分别生成和写入产物
const { output } = await bundle.generate(outputOptions);
await bundle.write(outputOptions);
}
} catch (error) {
buildFailed = true;
console.error(error);
}
if (bundle) {
// 最后调用 bundle.close 方法结束打包
await bundle.close();
}
process.exit(buildFailed ? 1 : 0);
}
build();
- 通过
rollup.rollup
方法,传入inputOptions
,生成 bundle 对象; - 调用 bundle 对象的 generate 和 write 方法,传入
outputOptions
,分别完成产物和生成和磁盘写入。 - 调用 bundle 对象的 close 方法来结束打包。
watch
// watch.js
const rollup = require("rollup");
const watcher = rollup.watch({
// 和 rollup 配置文件中的属性基本一致,只不过多了`watch`配置
input: "./src/index.js",
output: [
{
dir: "dist/es",
format: "esm",
},
{
dir: "dist/cjs",
format: "cjs",
},
],
watch: {
exclude: ["node_modules/**"],
include: ["src/**"],
},
});
// 监听 watch 各种事件
watcher.on("restart", () => {
console.log("重新构建...");
});
watcher.on("change", (id) => {
console.log("发生变动的模块id: ", id);
});
watcher.on("event", (e) => {
if (e.code === "BUNDLE_END") {
console.log("打包信息:", e);
}
});