@solumon/tracker
v0.3.3
Published
Vue 3 全埋点 SDK:点击/PV/曝光/性能/错误自动采集与手动埋点
Maintainers
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 为指标名,extData 含 value(毫秒,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',
},
}),
}),
)transport 与 reportUrl 至少配置其一;同时配置时走 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/