ctc-track-plugin
v1.4.4
Published
uniapp 小程序埋点劫持
Readme
CTC Track Plugin
项目简介
CTC Track Plugin 是一个专为 uniapp 小程序设计的智能埋点插件,通过编译时代码注入和运行时数据劫持的双重机制,实现用户行为数据的自动收集和批量上报。插件采用无侵入式设计,开发者无需手动添加埋点代码,即可获得完整的用户行为分析能力。
🚀 核心特性
- 🔄 双层架构:编译时AST分析 + 运行时行为劫持
- 📊 智能批处理:支持按数量/时间阈值自动批量上报
- ⚙️ 远程配置:动态获取服务端配置,支持开关控制
- 🔒 多环境适配:自动识别开发/测试/生产环境
- 🔁 重试机制:网络异常时自动重试,确保数据可靠性
- 📱 会话跟踪:自动生成会话ID和事件ID,支持完整链路追踪
🛠️ 功能模块
自动埋点
🔍 点击事件劫持
- 编译时注入:通过Vite插件在构建阶段自动分析Vue组件AST,为标记元素注入埋点代码
- 智能识别:自动识别带有
data-manual-track属性的元素 - 事件融合:与现有click事件无缝融合,不影响原有业务逻辑
- 标签信息收集:自动收集标签名、文本内容等上下文信息
📄 页面跳转埋点
- API拦截:通过
uni.addInterceptor拦截navigateTo等导航API - 页面栈分析:自动获取当前页面和来源页面信息
- 路径解析:基于
pages.json配置自动解析页面标题和路径 - Navigator组件支持:自动处理
<navigator>组件的跳转埋点
手动埋点
- 全局方法:提供
sendMd和sendPageMd全局方法 - 灵活调用:支持在任意Vue组件中通过实例方法调用
- 自定义参数:支持传递任意自定义参数和事件ID
- 类型安全:完整的TypeScript类型定义支持
📦 安装
环境要求
- Node.js: >= 16.0.0
- Vue: 3.4.21
- uniapp: 最新版本
- 构建工具: Vite
包管理器安装
# 使用 pnpm(推荐)
pnpm add ctc-track-plugin
# 使用 npm
npm install ctc-track-plugin
# 使用 yarn
yarn add ctc-track-plugin🚀 快速开始
第一步:配置Vite插件
在项目根目录的 vite.config.js 或 vite.config.ts 中配置编译时注入插件:
import { defineConfig } from 'vite'
import Uni from '@dcloudio/vite-plugin-uni'
import InjectClickHandler from 'ctc-track-plugin/inject'
export default defineConfig({
plugins: [
InjectClickHandler(), // 🚨 必须放在 Uni 插件之前
Uni()
]
})⚠️ 重要提示:
InjectClickHandler必须放在Uni插件之前,否则AST注入将失效。
第二步:初始化Vue插件
在 main.ts 中注册运行时插件:
import { createSSRApp } from 'vue'
import TrackAutomaticPlugin from 'ctc-track-plugin'
import pagesJson from '@/pages.json'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
const { baseUrl, environment } = getEnvBaseUrl(process.env.UNI_PLATFORM);
// 注册埋点插件
app.use(TrackAutomaticPlugin, {
app_entity_source: 402, // 应用实体来源ID
channel_source: 201, // 渠道来源ID
usertype: 'customer', // 用户类型(可选)
baseUrl, // 埋点API基础URL(必传参数)
}, pagesJson)
return { app }
}第三步:配置页面信息
确保 pages.json 中正确配置了页面路径和标题:
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
}
]
}📋 配置参数说明
初始化配置 (options)
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
| --------------------- | --------- | ---- | ------------ | ---------------------------------------- |
| app_entity_source | number | ✅ | - | 应用实体来源标识,用于区分不同业务线 |
| channel_source | number | ✅ | - | 渠道来源标识,用于追踪用户来源渠道 |
| usertype | string | ❌ | 'customer' | 用户类型,影响JWT签名和权限验证 |
| baseUrl | string | ✅ | - | 自定义埋点API基础URL,优先级高于自动识别 |
| enableTrack | boolean | ❌ | true | 是否启用埋点功能,可用于开发环境快速关闭 |
远程配置参数
插件会自动从服务端获取以下动态配置参数:
| 参数名 | 类型 | 默认值 | 说明 |
| ---------------- | -------- | ------ | ------------------------------- |
| batchSize | number | 100 | 批处理数据条数阈值 |
| intervalTime | number | 100 | 批处理时间间隔(秒) |
| retryCount | number | 3 | 网络请求失败重试次数 |
| activeSwitch | 0\|1 | 1 | 主动埋点开关(sendMd方法) |
| autoSwitch | 0\|1 | 1 | 自动埋点开关(页面跳转/点击事件) |
💡 提示:远程配置具有最高优先级,会覆盖本地默认配置。
🔨 开发与构建
本地开发
# 克隆项目
git clone <repository-url>
cd ctc-track-plugin
# 安装依赖
pnpm install
# 开发模式(监听文件变化)
pnpm start构建发布
# 构建生产版本
pnpm build
# 发布到npm(需要相应权限)
npm publish构建输出
dist/bury.js- ESM格式主模块dist/bury.cjs- CommonJS格式主模块dist/inject-click-handler.js- ESM格式Vite插件dist/inject-click-handler.cjs- CommonJS格式Vite插件dist/bury.d.ts- TypeScript类型定义文件
数据结构
埋点数据格式
每条埋点数据包含以下字段:
interface TrackData {
event_timestamp: string; // 事件时间戳
page_url: string; // 页面URL
page_id?: string; // 页面ID
refer_page_id?: string; // 来源页面ID
refer_page_url?: string; // 来源页面URL
event_type: 'click' | 'page_view'; // 事件类型
event_id?: string; // 事件ID
is_element: boolean; // 是否为元素事件
element_id?: string; // 元素ID
element_type?: string; // 元素类型
element_name?: string; // 元素名称
user_id?: string; // 用户ID
user_type?: string; // 用户类型
device_id: string; // 设备ID
platform: string; // 平台信息
os: string; // 操作系统
osVersion: string; // 系统版本
model: string; // 设备型号
brand: string; // 设备品牌
network_type: string; // 网络类型
session_id: string; // 会话ID
id: string; // 唯一标识
extra_params: Record<string, any>; // 额外参数
}高级功能
批处理机制
- 支持按数量和时间两种方式触发批量发送
- 达到批处理大小或超时时间会自动发送
- 支持发送失败时的重试机制
- 可通过服务端配置动态调整参数
数据安全
- 使用MD5生成唯一事件ID,避免数据重复
- 支持JWT token验证
- 自动处理用户身份信息
⚠️ 重要事项
🔧 技术依赖
| 依赖项 | 版本要求 | 说明 |
| -------------- | ----------- | ---------------------- |
| Vue | 3.4.21 | 核心框架,必须精确版本 |
| Node.js | >= 16.0.0 | 开发环境要求 |
| TypeScript | >= 5.0.0 | 类型支持 |
| Vite | >= 5.0.0 | 构建工具 |
🎯 兼容性说明
- ✅ 支持平台:uniapp 小程序(微信/支付宝/百度等)
- ❌ 不支持:H5端、App端(原生)
- 🔄 部分支持:H5端的环境自适应功能
🚨 关键配置
1. Vite插件顺序
// ✅ 正确配置
plugins: [
InjectClickHandler(), // 必须在前
Uni()
]
// ❌ 错误配置
plugins: [
Uni(),
InjectClickHandler() // 注入将失效
]2. 用户数据格式
插件依赖 uni.getStorageSync('user') 获取用户信息,格式要求:
// localStorage中user数据格式
{
userInfo: {
jwt: 'eyJhbGciOiJIUzI1NiIs...', // JWT token(可选)
usertype: 'customer' // 用户类型
}
}3. 性能优化建议
// 开发环境关闭埋点
app.use(TrackAutomaticPlugin, {
app_entity_source: 402,
channel_source: 201,
enableTrack: process.env.NODE_ENV === 'production' // 仅生产环境启用
}, pagesJson)API 文档
全局方法
sendMd(buryContent)
手动发送埋点数据
参数:
buryContent(Object): 埋点内容对象content(Object|String): 埋点事件内容event_id(String): 事件ID- 其他自定义参数
示例:
const instance = getCurrentInstance()?.proxy;
instance?.sendMd({
content: {
event_id: 'my_send_event_id',
customer_id: '555',
driver_id: '666',
car_type_id: '999',
},
});sendPageMd(url)
手动发送页面埋点数据
参数:
url(String): 页面URL路径
示例:
const instance = getCurrentInstance()?.proxy;
instance?.sendPageMd('/pages/home/index');💡 使用示例
自动埋点示例
点击事件自动埋点
<!-- 简单事件标记 -->
<button @click="handleSubmit" data-manual-track="submit_button">
提交表单
</button>
<!-- 复杂参数埋点 -->
<button @click="handlePay" :data-manual-track="{
event_id: 'payment_click',
amount: orderAmount,
payment_method: 'wechat'
}">
微信支付
</button>页面跳转自动埋点
<!-- Navigator组件自动埋点 -->
<navigator url="/pages/detail/index" open-type="navigate">
查看详情
</navigator>
<!-- 编程式跳转自动埋点 -->
<script setup>
const goToDetail = () => {
uni.navigateTo({
url: '/pages/detail/index?id=123'
})
}
</script>手动埋点示例
组合式API使用
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()?.proxy
// 发送自定义事件
const trackCustomEvent = () => {
instance?.sendMd({
content: {
event_id: 'custom_action',
user_behavior: 'scroll_to_bottom',
page_stay_time: 120
}
})
}
// 手动发送页面埋点
const trackPageView = () => {
instance?.sendPageMd('/pages/special/landing')
}选项式API使用
export default {
methods: {
async handleFormSubmit() {
// 业务逻辑
const result = await this.submitForm()
// 埋点上报
this.sendMd({
content: {
event_id: 'form_submit_result',
success: result.success,
form_type: 'user_register',
error_code: result.errorCode || null
},
tag: 'form',
text: '用户注册表单'
})
}
}
}版本历史
v1.2.9 (当前版本)
- 🎯 优化编译时注入:改进AST分析逻辑,提升代码注入准确性
- 🔧 完善配置管理:增强远程配置获取和本地缓存机制
- 📦 构建优化:使用tsup构建工具,支持CJS和ESM双格式输出
- 🛡️ 类型完善:优化TypeScript类型定义,提升开发体验
- 🌐 环境适配:改进多环境API地址自动切换逻辑
- 🔄 批处理增强:优化BatchProcessor类,提升数据处理效率
- 📱 设备信息:完善设备信息收集和会话管理机制
📚 故障排除
常见问题及解决方案
1. 埋点数据未上报
可能原因:
- 网络连接问题
- 远程配置开关关闭
- 用户信息存储格式错误
解决方案:
// 1. 检查网络状态
console.log('Network:', uni.getNetworkType())
// 2. 检查用户信息
const user = uni.getStorageSync('user')
console.log('User info:', user)
// 3. 检查配置状态
// 查看控制台输出的配置信息2. Vite插件不生效
可能原因:
- 插件顺序错误
- Vue文件格式问题
解决方案:
// 正确的插件配置
plugins: [
InjectClickHandler(), // 必须在Uni前面
Uni()
]
// 检查构建日志,确认有没有注入成功的信息3. 页面埋点缺失
可能原因:
pages.json配置不完整- 页面路径匹配问题
解决方案:
// 确保 pages.json 中有完整的页面信息
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
}
]
}调试模式
插件在开发环境下会输出详细的调试信息:
- 配置参数获取状态
- 批处理队列状态
- 数据发送结果
- 错误信息详情
请在控制台查看相关日志信息。
🔗 相关链接
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
贡献步骤
- Fork 项目到你的 Gitee 账号
- Clone 分支到本地
- 创建新分支开发新功能
- 提交代码并推送到远程仓库
- 创建 Pull Request
开发规范
- 遵循现有代码风格
- 添加必要的注释和文档
- 确保新功能的稳定性和兼容性
- 更新相关测试用例
📞 技术支持
如遇到问题,请提供以下信息:
- 插件版本号:
v1.2.9 - uniapp 版本
- Vue 版本
- 错误复现步骤
- 控制台错误信息
- 环境信息(开发/测试/生产)
📜 许可证
Copyright (c) 2024 CTC Team
