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 🙏

© 2026 – Pkg Stats / Ryan Hefner

web-monitor-tracking-component

v1.0.11

Published

一个轻量级的前端监控和埋点SDK,支持错误监控、性能监控、用户行为追踪和自定义事件上报。

Readme

Web Monitoring & Tracking SDK

一个轻量级的前端监控和埋点SDK,支持错误监控、性能监控、用户行为追踪和自定义事件上报。

安装

npm install watch-sdk --save

功能特点

  • 监控功能

    • 错误监控(JS异常、Promise拒绝、资源加载、API请求)
    • 性能监控(首屏时间、页面加载、API响应时间)
    • 白屏检测
    • 页面录屏回放
    • 用户行为追踪
  • 埋点功能

    • PV/UV统计
    • 用户点击行为追踪
    • 表单提交监控
    • 页面停留时长统计
    • 自定义事件上报
    • API性能指标采集
    • 动态用户ID设置(✨ 新功能)

📋 ID 管理机制

🔑 三种 ID 的职责划分

| ID 类型 | 用途 | 管理方式 | 持久性 | 用户控制 | |---------|------|----------|--------|----------| | distinctId | 访问者唯一标识 | 系统自动管理 | localStorage 持久化 | ❌ 不可设置 | | deviceId | 设备指纹标识 | 系统计算生成 | 会话期间有效 | ❌ 不可设置 | | userId | 业务用户标识 | 开发者控制 | 可选持久化 | ✅ 可动态设置 |

🛡️ 系统自动管理的 ID

distinctId(访问者ID)

// ✅ 系统自动处理,无需配置
const tracker = new Tracker({
  dsn: 'https://your-api.com',
  apikey: 'your-api-key',
  // distinctId 由系统自动生成和管理
});

// 系统会自动:
// 1. 检查 localStorage 中是否已存在
// 2. 不存在则生成新的 distinctId
// 3. 格式:vid_1703123456789_abc123def
// 4. 自动保存到 localStorage

deviceId(设备指纹)

// ✅ 基于设备特征自动计算
// 系统会自动:
// 1. 收集设备信息(userAgent、screen、platform等)
// 2. 使用 SHA-256 生成设备指纹
// 3. 相同设备始终生成相同的 deviceId
// 4. 不同设备生成不同的 deviceId

👤 开发者可控制的 ID

userId(业务用户ID)

// ✅ 用户登录后设置
tracker.setUserId('user_12345');

// ✅ 用户登出时清除
tracker.setUserId(null);

// ✅ 获取当前用户ID
const currentUserId = tracker.getUserId();

⚠️ 常见误区

❌ 错误做法

// ❌ 不要尝试传入 distinctId
const tracker = new Tracker({
  dsn: 'https://your-api.com',
  apikey: 'your-api-key',
  distinctId: 'my-custom-id' // 此字段已移除
});

// ❌ 不要尝试设置 deviceId
// deviceId 是系统计算的设备指纹,无法手动设置

✅ 正确做法

// ✅ 让系统自动管理 distinctId 和 deviceId
const tracker = new Tracker({
  dsn: 'https://your-api.com',
  apikey: 'your-api-key',
  autoTrack: true,
  enableHeatmap: true // 开启热力图功能,记录用户点击行为
});

// ✅ 只在必要时设置 userId
if (isUserLoggedIn) {
  tracker.setUserId(getCurrentUserId());
}

🎯 设计原理

  1. distinctId:确保每个访问者都有唯一标识,用于用户行为分析
  2. deviceId:识别设备特征,用于设备分析和反作弊
  3. userId:关联业务用户,用于用户画像和行为归因

这种设计确保了数据的唯一性一致性可靠性

快速开始

基础用法

SDK使用 mode 字段控制启用哪些功能:

import sdk from 'watch-sdk';

// 同时启用监控和埋点功能
sdk.init({
  dsn: 'https://your-server.com/api',
  apikey: 'your-project-key',
  mode: 'all', // 'monitoring', 'tracking', 'all'
  
  // 注意:userId 现在不需要在初始化时提供,可以动态设置
  
  // 监控特有配置
  monitoring: {
    silentRecordScreen: true
  },
  
  // 埋点特有配置
  tracking: {
    autoTrack: true,
    enableHeatmap: true, // 🎯 开启热力图功能
    sampling: { ratio: 1 }, // 采样率
    maxCache: 20, // 缓存配置
    apiFilter: {
      excludeUrls: ['/api/heartbeat'] // 过滤配置
    }
  }
});

// 用户登录后动态设置用户ID
sdk.setUserId('user123');

// 用户注销时清空用户ID
sdk.setUserId(null);

// 获取当前用户ID
const currentUserId = sdk.getUserId();

动态用户ID设置 ✨

在新版本中,您可以在用户登录后动态设置用户ID,无需在SDK初始化时提供:

// 1. 初始化SDK(无需userId)
sdk.init({
  dsn: 'https://your-server.com/api',
  apikey: 'your-project-key',
  mode: 'tracking'
});

// 2. 用户登录成功后设置userId
async function handleUserLogin(username, password) {
  try {
    const response = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password })
    });
    
    const userData = await response.json();
    
    if (userData.success) {
      // 动态设置用户ID
      sdk.setUserId(userData.userId);
      
      // 发送登录成功事件(自动包含userId)
      sdk.trackCustomEvent('user_login', {
        loginMethod: 'password',
        userType: userData.userType
      });
    }
  } catch (error) {
    console.error('登录失败:', error);
  }
}

// 3. 用户注销时清空userId
function handleUserLogout() {
  // 发送注销事件(包含当前userId)
  sdk.trackCustomEvent('user_logout', {
    logoutReason: 'user_action'
  });
  
  // 清空用户ID
  sdk.setUserId(null);
}

// 4. 检查当前用户状态
const userId = sdk.getUserId();
if (userId) {
  console.log('当前用户ID:', userId);
} else {
  console.log('用户未登录');
}

userId 字段特性

  • 全面覆盖:事件数据、设备信息、通用事件数据都包含 userId 字段
  • 动态设置:支持运行时动态设置和清空用户ID
  • 数据一致性:所有模块同步更新用户ID
  • 向后兼容:不影响现有代码的正常运行

userId vs distinctId

| 字段 | 说明 | 生成时机 | 用途 | |------|------|----------|------| | distinctId | 访客唯一标识 | SDK初始化时自动生成 | 区分不同访客,匿名用户追踪 | | userId | 用户唯一标识 | 用户登录后手动设置 | 关联具体用户,登录用户追踪 |

Vue 中使用

import Vue from 'vue';
import sdk from 'watch-sdk';

Vue.use(sdk, {
  dsn: 'https://your-server.com/api',
  apikey: 'your-project-key',
  mode: 'all'
});

// 在Vue组件中动态设置用户ID
export default {
  methods: {
    async login() {
      // 登录逻辑...
      const userData = await this.callLoginAPI();
      
      // 设置用户ID
      sdk.setUserId(userData.userId);
    },
    
    logout() {
      // 清空用户ID
      sdk.setUserId(null);
    }
  }
}