add plugin API recipe

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent 35c6f20164
commit 8c17ef02ec
4 changed files with 215 additions and 5 deletions

View File

@@ -72,3 +72,9 @@ Starting with a later version of v0.9.11, we add the ability to record and play
This feature aims to provide developers with more information about the bug scene. There are some options for recording and replaying console output.
[link](./console.md)
### Plugin
The plugin API is designed to extend the function of rrweb without bump the size and complexity of rrweb's core part.
[link](./plugin.md)

View File

@@ -69,3 +69,9 @@ Canvas 是一种特殊的 HTML 元素,默认情况下其内容不会被 rrweb
从 v0.9.11 的下一个版本开始,我们增加了录制和播放控制台输出的功能。这个功能旨在为开发者提供更多的 bug 信息。对这项功能我们还提供了一些设置选项。
[链接](./console.zh_CN.md)
### 插件
插件 API 的设计目标是在不增加 rrweb 核心部分大小和复杂性的前提下,扩展 rrweb 的功能。
[链接](./plugin.zh_CN.md)

99
docs/recipes/plugin.md Normal file
View File

@@ -0,0 +1,99 @@
# Plugin
The plugin API is designed to extend the function of rrweb without bump the size and complexity of rrweb's core part.
## Interface
Same to with other functionality in rrweb, a plugin can implement record or replay or both features.
```ts
export type RecordPlugin<TOptions = unknown> = {
name: string;
observer: (cb: Function, options: TOptions) => listenerHandler;
options: TOptions;
};
export type ReplayPlugin = {
handler: (
event: eventWithTime,
isSync: boolean,
context: { replayer: Replayer },
) => void;
};
```
Both record and replay plugins have a type interface.
### example
#### record plugin
```ts
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
name: 'my-scope/example@1',
observer(cb, options) {
const timer = setInterval(() => {
cb({
foo: options.foo,
timestamp: Date.now(),
});
}, 1000);
return () => clearInterval(timer);
},
options: {
foo: 'bar',
},
};
rrweb.record({
emit: emit(event) {},
plugins: [exampleRecordPlugin],
});
```
In this example, the record plugin will emit events like this:
```js
{
type: 6,
data: {
plugin: 'my-scope/example@1',
payload: {
foo: 'bar',
timestamp: 1624693882345,
},
},
timestamp: 1624693882345,
}
```
#### replay plugin
```ts
const exampleReplayPlugin: ReplayPlugin = {
handler(event, isSync, context) {
if (event.type === EventType.Plugin) {
// do something with event.data.payload
if (event.data.plugin === 'my-scope/example@1') {
// handle example plugin data
}
}
},
};
const replayer = new rrweb.Replayer(events, {
plugins: [exampleReplayPlugin],
});
```
A replay plugin can interact with the replayer by using `context.replayer`.
## naming a plugin
A record plugin should have a unique name, and it will be stored in the event it emits.
**Since we will have both plugins in the rrweb repo and plugins in users' own codebase, which may cause naming conflicts in the future, we strongly recommended users naming their own plugins in this way:**
> scope/name@version
For example `rrweb/console@1` or `github/pr@2`.

View File

@@ -0,0 +1,99 @@
# 插件
插件 API 的设计目标是在不增加 rrweb 核心部分大小和复杂性的前提下,扩展 rrweb 的功能。
## 接口
与 rrweb 其它功能相似,插件可以包含同时包含录制、回放侧的功能,也可以只实现其中任一。
```ts
export type RecordPlugin<TOptions = unknown> = {
name: string;
observer: (cb: Function, options: TOptions) => listenerHandler;
options: TOptions;
};
export type ReplayPlugin = {
handler: (
event: eventWithTime,
isSync: boolean,
context: { replayer: Replayer },
) => void;
};
```
以上是录制和回放插件的接口类型。
### 示例
#### 录制侧插件
```ts
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
name: 'my-scope/example@1',
observer(cb, options) {
const timer = setInterval(() => {
cb({
foo: options.foo,
timestamp: Date.now(),
});
}, 1000);
return () => clearInterval(timer);
},
options: {
foo: 'bar',
},
};
rrweb.record({
emit: emit(event) {},
plugins: [exampleRecordPlugin],
});
```
在这个示例中,录制侧插件将会输出这样的事件:
```js
{
type: 6,
data: {
plugin: 'my-scope/example@1',
payload: {
foo: 'bar',
timestamp: 1624693882345,
},
},
timestamp: 1624693882345,
}
```
#### 回放侧插件
```ts
const exampleReplayPlugin: ReplayPlugin = {
handler(event, isSync, context) {
if (event.type === EventType.Plugin) {
// 使用 event.data.payload
if (event.data.plugin === 'my-scope/example@1') {
// 处理示例插件录制的数据
}
}
},
};
const replayer = new rrweb.Replayer(events, {
plugins: [exampleReplayPlugin],
});
```
回放侧插件可以通过 `context.replayer` 与播放器进行交互。
## 插件命名
录制侧插件应该拥有全局唯一的名称,并且其名称会被记录在输出的事件中。
**由于会同时存在 rrweb 仓库中的官方插件与用户自行实现的自定义插件,所以我们推荐使用统一的命名规则避免冲突,命名方式如下:**
> scope/name@version
例如: `rrweb/console@1``github/pr@2`