npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

watch-tower-vue

v1.0.0

Published

A Vue3 plugin for session recording and performance monitoring using RRWeb

Readme

Watch Tower Vue

一个基于 RRWeb 的 Vue3 插件,用于录制和回放用户会话,帮助你更好地理解用户行为和调试问题。

特性

  • 完整的用户会话录制(点击、输入、滚动等)
  • 支持 Canvas 录制
  • 控制台日志录制
  • Vue3 组合式 API(Composables)
  • TypeScript 类型支持
  • 灵活的配置选项
  • 自动或手动录制模式
  • 导出录制数据

安装

npm install watch-tower-vue
# 或
yarn add watch-tower-vue
# 或
pnpm add watch-tower-vue

基本使用

1. 作为 Vue 插件使用

main.jsmain.ts 中:

import { createApp } from 'vue';
import App from './App.vue';
import WatchTower from 'watch-tower-vue';

const app = createApp(App);

// 安装插件
app.use(WatchTower, {
  maxDuration: 10 * 60 * 1000, // 最大录制时长 10 分钟
  recordCanvas: true,          // 录制 Canvas
  collectFonts: true,          // 收集字体
  recordLog: true,             // 录制控制台日志
  autoStart: false,            // 不自动开始录制
});

app.mount('#app');

2. 在组件中使用 Composables API

<template>
  <div>
    <h1>Watch Tower Demo</h1>

    <div class="controls">
      <button @click="startRecording" :disabled="isRecording">
        开始录制
      </button>
      <button @click="stopRecording" :disabled="!isRecording">
        停止录制
      </button>
      <button @click="saveToLocalStorage" :disabled="isRecording">
        保存录制
      </button>
      <button @click="exportToFile" :disabled="isRecording">
        导出文件
      </button>
    </div>

    <div class="stats">
      <p>录制状态: {{ isRecording ? '录制中' : '已停止' }}</p>
      <p>录制时长: {{ formattedDuration }}</p>
      <p>事件数量: {{ eventCount }}</p>
    </div>
  </div>
</template>

<script setup>
import { useRecorder } from 'watch-tower-vue';

const {
  isRecording,
  eventCount,
  formattedDuration,
  startRecording,
  stopRecording,
  saveToLocalStorage,
  exportToFile,
} = useRecorder();
</script>

3. 使用全局属性

在选项式 API 中:

<script>
export default {
  mounted() {
    // 通过 this.$recorder 访问
    this.$recorder.startRecording({
      maxDuration: 5 * 60 * 1000,
    });
  },
  beforeUnmount() {
    this.$recorder.stopRecording();
  }
}
</script>

4. 直接使用 Recorder 类

import { RRwebRecorder } from 'watch-tower-vue';

const recorder = new RRwebRecorder({
  maxDuration: 5 * 60 * 1000,
  recordCanvas: true,
});

// 开始录制
recorder.startRecording();

// 停止录制
const events = recorder.stopRecording();

// 保存到 localStorage
recorder.saveToLocalStorage('my-recording');

// 导出为文件
recorder.exportToFile('recording.json');

配置选项

interface RecorderOptions {
  maxDuration?: number;        // 最大录制时长(毫秒),默认 5 分钟
  collectAllData?: boolean;    // 是否收集所有数据,默认 true
  recordCanvas?: boolean;      // 是否录制 canvas,默认 true
  collectFonts?: boolean;      // 是否收集字体,默认 true
  recordLog?: boolean;         // 是否录制控制台日志,默认 true
  autoStart?: boolean;         // 是否自动开始录制,默认 false
  onEventEmit?: (event) => void; // 事件触发回调
}

API 参考

useRecorder()

返回一个包含以下属性和方法的对象:

响应式状态

  • isRecording: Ref<boolean> - 是否正在录制
  • events: Ref<any[]> - 事件列表
  • eventCount: Ref<number> - 事件数量
  • recordingDuration: Ref<number> - 录制时长(秒)
  • formattedDuration: Ref<string> - 格式化的时长 (mm:ss)

方法

  • startRecording(options?) - 开始录制
  • stopRecording() - 停止录制,返回事件列表
  • saveToLocalStorage(key?) - 保存到 localStorage
  • exportToFile(filename?) - 导出为 JSON 文件
  • clearEvents() - 清空事件
  • getEvents() - 获取事件列表

RRwebRecorder 类

实例方法

  • startRecording(options?) - 开始录制
  • stopRecording() - 停止录制
  • getEvents() - 获取事件列表
  • getRecordingStatus() - 获取录制状态
  • clearEvents() - 清空事件
  • saveToLocalStorage(key?) - 保存到 localStorage
  • exportToFile(filename?) - 导出为文件
  • reportEvent(event) - 上报单个事件

静态方法

  • RRwebRecorder.loadFromLocalStorage(key?) - 从 localStorage 加载
  • RRwebRecorder.clearLocalStorage(key?) - 清除 localStorage

高级用法

自定义事件回调

app.use(WatchTower, {
  onEventEmit: (event) => {
    console.log('录制事件:', event);
    // 可以在这里实时上报到服务器
    fetch('/api/recording/event', {
      method: 'POST',
      body: JSON.stringify(event),
    });
  }
});

条件录制

import { useRecorder } from 'watch-tower-vue';

const { startRecording } = useRecorder();

// 只在出现错误时开始录制
window.addEventListener('error', () => {
  startRecording({
    maxDuration: 2 * 60 * 1000, // 错误发生后录制 2 分钟
  });
});

与路由集成

import { useRecorder } from 'watch-tower-vue';
import { useRouter } from 'vue-router';

const router = useRouter();
const { startRecording, stopRecording, saveToLocalStorage } = useRecorder();

// 每次路由变化时保存录制
router.afterEach(() => {
  if (isRecording.value) {
    stopRecording();
    saveToLocalStorage();
    startRecording(); // 开始新的录制
  }
});

回放录制内容

要回放录制的内容,你需要使用 rrweb-player

npm install rrweb-player
<template>
  <div ref="playerContainer"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
import { RRwebRecorder } from 'watch-tower-vue';

const playerContainer = ref(null);

onMounted(() => {
  // 从 localStorage 加载录制数据
  const data = RRwebRecorder.loadFromLocalStorage();

  if (data && playerContainer.value) {
    new rrwebPlayer({
      target: playerContainer.value,
      props: {
        events: data.events,
        width: 1024,
        height: 768,
      },
    });
  }
});
</script>

浏览器兼容性

  • Chrome >= 60
  • Firefox >= 55
  • Safari >= 11
  • Edge >= 79

注意事项

  1. 录制数据可能会很大,建议设置合理的 maxDuration
  2. 敏感信息(如密码)默认会被屏蔽
  3. localStorage 有存储限制(通常 5-10MB)
  4. 生产环境建议将录制数据上传到服务器而不是保存在本地

License

ISC

贡献

欢迎提交 Issue 和 Pull Request!

相关链接