插件开发
插件概述
Rollup 插件是一个对象,具有 属性、构建钩子 和 输出生成钩子 中的一个或多个,并遵循我们的 约定。插件应作为一个导出一个函数的包进行发布,该函数可以使用插件特定的选项进行调用并返回此类对象。
插件允许你通过例如在打包之前进行转译代码或在node_modules
文件夹中查找第三方模块来自定义 Rollup 的行为。有关如何使用它们的示例,请参见 使用插件。
插件列表可以在 github.com/rollup/awesome 上找到。如果你想给某个插件提交建议,请提交一个 Pull Request。
一个简单的示例
以下插件将拦截任何不通过访问文件系统的 virtual-module
导入。例如,如果你想在浏览器中使用 Rollup,则需要这样做。它甚至可以用来替换入口点,如示例所示。
// @filename: rollup-plugin-my-example.js
// ---cut-start---
/** @returns {import('rollup').Plugin} */
// ---cut-end---
export default function myExample () {
return {
name: 'my-example', // 此名称将出现在警告和错误中
resolveId ( source ) {
if (source === 'virtual-module') {
// 这表示 rollup 不应询问其他插件或
// 从文件系统检查以找到此 ID
return source;
}
return null; // 其他ID应按通常方式处理
},
load ( id ) {
if (id === 'virtual-module') {
// "virtual-module"的源代码
return 'export default "This is virtual!"';
}
return null; // 其他ID应按通常方式处理
}
};
}
// @filename: rollup.config.js
import myExample from './rollup-plugin-my-example.js';
export default ({
input: 'virtual-module', // 由我们的插件解析
plugins: [myExample()],
output: [{
file: 'bundle.js',
format: 'es'
}]
});
约定
- 插件应该有一个明确的名称,并以
rollup-plugin-
作为前缀。 - 在
package.json
中包含rollup-plugin
关键字。 - 插件应该被测试,我们推荐 mocha 或 ava,它们支持 Promise。
- 可能的话,使用异步方法,例如
fs.readFile
而不是fs.readFileSync
- 用英文文档描述你的插件。
- 确保如果适当,你的插件输出正确的源映射。
- 如果插件使用“虚拟模块”(例如用于辅助函数),请使用
\0
前缀模块 ID。这可以防止其他插件尝试处理它。
属性
name
类型: | string |
插件的名称,用于在警告和错误消息中标识插件。
version
类型: | string |
插件的版本,用于插件间通信场景。
构建钩子
为了与构建过程交互,你的插件对象包括“钩子”。钩子是在构建的各个阶段调用的函数。钩子可以影响构建的运行方式,提供关于构建的信息,或在构建完成后修改构建。有不同种类的钩子:
async
:该钩子也可以返回一个解析为相同类型的值的 Promise;否则,该钩子被标记为sync
。first
:如 果有多个插件实现此钩子,则钩子按顺序运行,直到钩子返回一个不是null
或undefined
的值。sequential
:如果有多个插件实现此钩子,则所有这些钩子将按指定的插件顺序运行。如果钩子是async
,则此类后续钩子将等待当前钩子解决后再运行。parallel
:如果有多个插件实现此钩子,则所有这些钩子将按指定的插件顺序运行。如果钩子是async
,则此类后续钩子将并行运行,而不是等待当前钩子。
除了函数之外,钩子也可以是对象。在这种情况下,实际的钩子函数(或 banner/footer/intro/outro
的值)必须指定为 handler
。这允许你提供更多的可选属性,以改变钩子的执行:
-
order: "pre" | "post" | null
如果有多个插件实现此钩子,则可以先运行此插件("pre"
),最后运行此插件("post"
),或在用户指定的位置运行(没有值或null
)。// ---cut-start---
/** @returns {import('rollup').Plugin} */
// ---cut-end---
export default function resolveFirst() {
return {
name: 'resolve-first',
resolveId: {
order: 'pre',
handler(source) {
if (source === 'external') {
return { id: source, external: true };
}
return null;
}
}
};
}如果有多个插件使用
"pre"
或"post"
,Rollup 将按用户指定的顺序运行它们。此选项可用于所有插件钩子。对于并行钩子,它会更改同步部分运行的顺序。 -
sequential: boolean
不要与其他插件的相同钩子并行运行此钩子。仅可用于parallel
钩子。使用此选项将使 Rollup 等待所有先前插件的结果,然后执行插件钩子,然后再次并行运行剩余的插件。例如,当你有插件A
、B
、C
、D
、E
,它们都实现了相同的并行钩子,并且中间插件C
具有sequential: true
时,Rollup 将首先并行运行A + B
,然后单独运行C
,然后再次并行运行D + E
。当你需要在不同的
writeBundle
钩子中运行多个命令行工具并相互依赖时,这可能很有用(请注意,如果可能,建议在顺序generateBundle
钩子中添加/删除文件,这样更快,适用于纯内存构建,并允许其他内存构建插件查看文件)。你可以将此选项与order
结合使用进行排序。import path from 'node:path';
import { readdir } from 'node:fs/promises';
// ---cut-start---
/** @returns {import('rollup').Plugin} */
// ---cut-end---
export default function getFilesOnDisk() {
return {
name: 'getFilesOnDisk',
writeBundle: {
sequential: true,
order: 'post',
async handler({ dir }) {
const topLevelFiles = await readdir(path.resolve(dir));
console.log(topLevelFiles);
}
}
};
}
构建钩子在构建阶段运行,该阶段由 rollup.rollup(inputOptions)
触发。它们主要涉及在 Rollup 处理输入文件之前定位、提供和转换输入文件。构建阶段的第一个钩子是 options
,最后一个钩子始终是 buildEnd
。如果有构建错误,则在此之后将调用 closeBundle
。
parallel
sequential
first
async
sync
此外,在监视模式下,watchChange
钩子可以在任何时候触发,以通知当前运行生成输出后将触发新的运行。另外,当监视器关闭时,closeWatcher
钩子将被触发。
有关在输出生成阶段运行以修改生成的输出的钩子,请参见 输出生成钩子。
buildEnd
类型: | (error?: Error) => void |
类别: | async, parallel |
上一个钩子: | moduleParsed 、resolveId 或 resolveDynamicImport |
下一个钩子: | 输出生成阶段的 outputOptions ,因为这是构建阶段的最后一个钩子 |