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

@solumon/tracker

v0.3.3

Published

Vue 3 全埋点 SDK:点击/PV/曝光/性能/错误自动采集与手动埋点

Readme

@solumon/tracker

Vue 3 全埋点 SDK。采用「核心 + 插件」架构,自动采集点击、PV/停留时长、元素曝光、性能指标与错误,支持手动埋点,批量上报到后端接口。

安装

npm i @solumon/tracker

依赖 vue@^3,vue-router@^4 为可选 peer 依赖(用于路由级 PV 与页面名解析)。

快速接入

import { createApp } from 'vue'
import { createTracker } from '@solumon/tracker'
import router from './router'

const app = createApp(App)
app.use(router)
app.use(
  createTracker({
    reportUrl: 'https://xxx/collect',
    source: 'H5',                    // 默认 'H5'
    h5Ver: 'jc-mfxy-tlmf-main',      // 建议构建时注入版本/分支标识
    router,                          // 可选,传入后 page 取 route.meta.trackPage
  }),
)
app.mount('#app')

路由中声明页面语义名:

{ path: '/special', component: SpecialList, meta: { trackPage: 'magic_listening_special_list' } }

报文格式

每条事件结构如下,默认以 JSON 数组批量 POST(Content-Type: application/json):

{
  "evTime": "2026-01-21 15:39:39",
  "source": "H5",
  "h5Ver": "jc-mfxy-tlmf-main",
  "page": "magic_listening_special_list",
  "event": "CLICK",
  "control": "click_special_training_item",
  "extData": { "id": "fb1f8ac2...", "title": "时间与数字", "status": 1 }
}

内置 event 枚举:CLICK(点击)、VIEW(PV/停留时长)、EXPOSE(曝光)、PERF(性能)、ERROR(错误),手动埋点可自定义。

后端报文包装协议不同时,用 transformPayload 做最终转换:

createTracker({
  reportUrl: '...',
  transformPayload: (events) => ({ list: events }),
})

采集能力

点击全埋点(CLICK)

自动监听全站点击。模板中用 data-track 声明控件标识,data-track-* 声明业务参数:

<div
  data-track="click_special_training_item"
  :data-track-id="item.id"
  :data-track-title="item.title"
  :data-track-status="item.status"
>

点击后自动上报 control: "click_special_training_item"extData: { id, title, status }(数字/布尔值自动还原类型)。点击子元素会向上查找最近的 data-track 祖先。

未标注的元素默认也会上报,control 固定为 AUTO_CLICK,extData.elPath 为自动生成的元素路径(如 div#app>main>button.submit:nth-child(2)),extData.text 为清洗后的文本(掩码长数字、截断)。

PV 与停留时长(VIEW)

路由切换时上报 control: "ENTER_PAGE"extData.pgPath;离开页面(含关页)时上报 control: "LEAVE_PAGE"extData.duration(毫秒)。未传 router 时自动 patch History API 兜底。

元素曝光(EXPOSE)

<div v-track-expose="{ control: 'expose_banner', extData: { id: 1 } }">
<!-- 或简写 -->
<div v-track-expose="'expose_banner'">

基于 IntersectionObserver,默认可见 50% 触发、同一元素只报一次。

性能指标(PERF)

基于 web-vitals 上报 FCP/LCP/CLS/INP/TTFB,control 为指标名,extDatavalue(毫秒,CLS 为 ×1000 取整)与 rating

错误监控(ERROR)

| control | 说明 | | --- | --- | | js_error | JS 运行时错误 | | unhandled_rejection | 未捕获的 Promise 异常 | | vue_error | Vue errorHandler 捕获的组件错误(不吞错,保留原有 handler) | | resource_error | 图片/脚本/样式加载失败 | | api_error | fetch/XHR 非 2xx 或网络失败(自动跳过埋点接口自身) |

同一错误指纹默认最多上报 3 次。

手动埋点

import { useTracker, getTracker } from '@solumon/tracker'

// 组件内
const tracker = useTracker()
tracker.track('CLICK', 'click_special_training_item', { id: 'fb1f...', status: 1 })

// 组件外(工具函数、store 等)
getTracker()?.track('ORDER', 'order_submit', { orderId: '123' })

完整配置

createTracker({
  reportUrl: '/collect',        // HTTP 上报地址;使用 transport 时可省略
  transport: undefined,         // 自定义上报通道(WebView JSBridge 等),优先于 HTTP
  enrichEvent: undefined,       // 入队前单条 enrichment(注入业务字段)
  source: 'H5',
  h5Ver: '',
  router,                       // 可选
  debug: false,                 // true 时事件仅打印控制台,不发请求
  sampleRate: 1,                // 会话级采样率 0~1
  batchSize: 10,                // 攒够 N 条立即上报;WebView 桥建议设为 1
  flushInterval: 5000,          // 最长等待毫秒数
  transformPayload: undefined,  // 批量报文最终转换(仅默认 HTTP 通道)
  plugins: {                    // 默认全部开启;false 关闭,对象为插件配置
    click: { ignoreSelectors: ['.sensitive'], reportUnmarked: true, maxTextLength: 50 },
    pv: { trackDuration: true },
    expose: { threshold: 0.5, once: true },
    performance: true,
    error: { captureNetwork: true, maxPerFingerprint: 3 },
  },
})

WebView 客户端上报

App WebView 场景通常走原生桥(如 uploadUserLog),不发 HTTP。注入 transport 即可,SDK 不耦合具体 JSBridge:

import { uploadUserLog } from '@up366/u3-flip-sdk'
import { createTracker } from '@solumon/tracker'
import pkg from '../package.json'

app.use(
  createTracker({
    source: 'H5',
    h5Ver: `${pkg.name} ${pkg.version}`,
    // 桥一般逐条接收,关闭批量
    batchSize: 1,
    transport: async (events) => {
      for (const event of events) {
        await uploadUserLog(event)
      }
    },
    // 对齐业务侧公共字段
    enrichEvent: (event) => ({
      ...event,
      ...getExamTrackBizFields(),
      extData: {
        ...event.extData,
        gitPro: pkg.name,
        platform: 'Client',
      },
    }),
  }),
)

transportreportUrl 至少配置其一;同时配置时走 transport。关页 flush 仍会触发,context.useBeacon 可供桥侧按需处理(多数原生桥可忽略)。

上报可靠性

  • 队列攒够 batchSize 条或等满 flushInterval 毫秒批量上报
  • 关页/切后台时强制 flush:默认 HTTP 优先 sendBeacon(超 60KB 或不支持时降级 fetch keepalive);自定义 transport 则直接回调
  • 上报失败静默,不影响业务

本地开发

在 monorepo 根目录:

pnpm install
pnpm dev:tracker   # 启动 packages/tracker/playground
pnpm --filter @solumon/tracker test    # 单元测试
pnpm --filter @solumon/tracker build   # 构建 ESM/CJS + 类型声明到 dist/