diff --git a/guide.md b/guide.md index 76f781d096..8a2ddb820f 100644 --- a/guide.md +++ b/guide.md @@ -311,6 +311,7 @@ The replayer accepts options as its constructor's second parameter, and it has t | logConfig | - | configuration of console output playback, refer to the [console recipe](./docs/recipes/console.md) | | plugins | [] | load plugins to provide extended replay functions. [What is plugins?](./docs/recipes/plugin.md) | | useVirtualDom | true | whether to use Virtual Dom optimization in the process of skipping to a new point of time | +| logger | console | The logger object used by the replayer to print warnings or errors | #### Use rrweb-player diff --git a/guide.zh_CN.md b/guide.zh_CN.md index 1093dbb386..ddb9038313 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -306,6 +306,7 @@ replayer.destroy(); | unpackFn | - | 数据解压缩函数,详见[优化存储策略](./docs/recipes/optimize-storage.zh_CN.md) | | plugins | [] | 加载插件以获得额外的回放功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) | | useVirtualDom | true | 在播放器跳转到一个新的时间点的过程中,是否使用 Virtual Dom 优化 | +| logger | console | 当播放器出现警告或错误时用来打印日志的对象 | #### 使用 rrweb-player diff --git a/packages/rrweb/src/replay/index.ts b/packages/rrweb/src/replay/index.ts index ce4dc6d8cb..cdc888e69b 100644 --- a/packages/rrweb/src/replay/index.ts +++ b/packages/rrweb/src/replay/index.ts @@ -184,6 +184,7 @@ export class Replayer { pauseAnimation: true, mouseTail: defaultMouseTailConfig, useVirtualDom: true, // Virtual-dom optimization is enabled by default. + logger: console, }; this.config = Object.assign({}, defaultConfig, config); @@ -259,9 +260,7 @@ export class Replayer { ); value.node = realNode; } catch (error) { - if (this.config.showWarning) { - console.warn(error); - } + this.warn(error); } } } @@ -486,7 +485,7 @@ export class Replayer { } public resume(timeOffset = 0) { - console.warn( + this.warn( `The 'resume' was deprecated in 1.0. Please use 'play' method which has the same interface.`, ); this.play(timeOffset); @@ -743,10 +742,10 @@ export class Replayer { isSync = false, ) { if (!this.iframe.contentDocument) { - return console.warn('Looks like your replayer has been destroyed.'); + return this.warn('Looks like your replayer has been destroyed.'); } if (Object.keys(this.legacy_missingNodeRetryMap).length) { - console.warn( + this.warn( 'Found unresolved missing node map', this.legacy_missingNodeRetryMap, ); @@ -1240,12 +1239,10 @@ export class Replayer { mediaEl.playbackRate = d.playbackRate; } } catch (error) { - if (this.config.showWarning) { - console.warn( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions - `Failed to replay media interactions: ${error.message || error}`, - ); - } + this.warn( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions + `Failed to replay media interactions: ${error.message || error}`, + ); } break; } @@ -1302,9 +1299,7 @@ export class Replayer { ); this.iframe.contentDocument?.fonts.add(fontFace); } catch (error) { - if (this.config.showWarning) { - console.warn(error); - } + this.warn(error); } break; } @@ -1342,9 +1337,7 @@ export class Replayer { ); if (virtualNode) value.node = virtualNode; } catch (error) { - if (this.config.showWarning) { - console.warn(error); - } + this.warn(error); } } } @@ -1425,7 +1418,7 @@ export class Replayer { const appendNode = (mutation: addedNodeMutation) => { if (!this.iframe.contentDocument) { - return console.warn('Looks like your replayer has been destroyed.'); + return this.warn('Looks like your replayer has been destroyed.'); } let parent: Node | null | ShadowRoot | RRNode = mirror.getNode( mutation.parentId, @@ -1704,12 +1697,10 @@ export class Replayer { value, ); } catch (error) { - if (this.config.showWarning) { - console.warn( - 'An error occurred may due to the checkout feature.', - error, - ); - } + this.warn( + 'An error occurred may due to the checkout feature.', + error, + ); } } else if (attributeName === 'style') { const styleValues = value; @@ -2122,20 +2113,20 @@ export class Replayer { * is microtask, so events fired on a removed DOM may emit * snapshots in the reverse order. */ - this.debug(REPLAY_CONSOLE_PREFIX, `Node with id '${id}' not found. `, d); + this.debug(`Node with id '${id}' not found. `, d); } private warn(...args: Parameters) { if (!this.config.showWarning) { return; } - console.warn(REPLAY_CONSOLE_PREFIX, ...args); + this.config.logger.warn(REPLAY_CONSOLE_PREFIX, ...args); } private debug(...args: Parameters) { if (!this.config.showDebug) { return; } - console.log(REPLAY_CONSOLE_PREFIX, ...args); + this.config.logger.log(REPLAY_CONSOLE_PREFIX, ...args); } } diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index fb3a300b40..e2cde98f8a 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -180,6 +180,10 @@ export type playerConfig = { }; unpackFn?: UnpackFn; useVirtualDom: boolean; + logger: { + log: (...args: Parameters) => void; + warn: (...args: Parameters) => void; + }; plugins?: ReplayPlugin[]; };