UNPKG

ctc-track-plugin

Version:

uniapp 小程序埋点劫持

548 lines (425 loc) 14.6 kB
# CTC Track Plugin [![npm version](https://img.shields.io/npm/v/ctc-track-plugin.svg)](https://www.npmjs.com/package/ctc-track-plugin) [![license](https://img.shields.io/npm/l/ctc-track-plugin.svg)](https://github.com/your-org/ctc-track-plugin/blob/main/LICENSE) ## 项目简介 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 ### 包管理器安装 ```bash # 使用 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` 中配置编译时注入插件: ```typescript 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` 中注册运行时插件: ```typescript 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` 中正确配置了页面路径和标题: ```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` | 自动埋点开关(页面跳转/点击事件) | > 💡 **提示**:远程配置具有最高优先级,会覆盖本地默认配置。 ## 🔨 开发与构建 ### 本地开发 ```bash # 克隆项目 git clone <repository-url> cd ctc-track-plugin # 安装依赖 pnpm install # 开发模式(监听文件变化) pnpm start ``` ### 构建发布 ```bash # 构建生产版本 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类型定义文件 ## 数据结构 ### 埋点数据格式 每条埋点数据包含以下字段: ```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插件顺序 ```typescript // ✅ 正确配置 plugins: [ InjectClickHandler(), // 必须在前 Uni() ] // ❌ 错误配置 plugins: [ Uni(), InjectClickHandler() // 注入将失效 ] ``` #### 2. 用户数据格式 插件依赖 `uni.getStorageSync('user')` 获取用户信息,格式要求: ```typescript // localStorage中user数据格式 { userInfo: { jwt: 'eyJhbGciOiJIUzI1NiIs...', // JWT token(可选) usertype: 'customer' // 用户类型 } } ``` #### 3. 性能优化建议 ```typescript // 开发环境关闭埋点 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 - 其他自定义参数 **示例:** ```javascript 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路径 **示例:** ```javascript const instance = getCurrentInstance()?.proxy; instance?.sendPageMd('/pages/home/index'); ``` ## 💡 使用示例 ### 自动埋点示例 #### 点击事件自动埋点 ```html <!-- 简单事件标记 --> <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> ``` #### 页面跳转自动埋点 ```html <!-- Navigator组件自动埋点 --> <navigator url="/pages/detail/index" open-type="navigate"> 查看详情 </navigator> <!-- 编程式跳转自动埋点 --> <script setup> const goToDetail = () => { uni.navigateTo({ url: '/pages/detail/index?id=123' }) } </script> ``` ### 手动埋点示例 #### 组合式API使用 ```typescript 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使用 ```javascript 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. 埋点数据未上报 **可能原因:** - 网络连接问题 - 远程配置开关关闭 - 用户信息存储格式错误 **解决方案:** ```javascript // 1. 检查网络状态 console.log('Network:', uni.getNetworkType()) // 2. 检查用户信息 const user = uni.getStorageSync('user') console.log('User info:', user) // 3. 检查配置状态 // 查看控制台输出的配置信息 ``` #### 2. Vite插件不生效 **可能原因:** - 插件顺序错误 - Vue文件格式问题 **解决方案:** ```typescript // 正确的插件配置 plugins: [ InjectClickHandler(), // 必须在Uni前面 Uni() ] // 检查构建日志,确认有没有注入成功的信息 ``` #### 3. 页面埋点缺失 **可能原因:** - `pages.json` 配置不完整 - 页面路径匹配问题 **解决方案:** ```json // 确保 pages.json 中有完整的页面信息 { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } } ] } ``` ### 调试模式 插件在开发环境下会输出详细的调试信息: - 配置参数获取状态 - 批处理队列状态 - 数据发送结果 - 错误信息详情 请在控制台查看相关日志信息。 ## 🔗 相关链接 - [NPM 包地址](https://www.npmjs.com/package/ctc-track-plugin) - [GitHub 仓库](https://github.com/your-org/ctc-track-plugin) - [uniapp 官方文档](https://uniapp.dcloud.net.cn/) - [Vue 3 官方文档](https://cn.vuejs.org/) - [Vite 官方文档](https://cn.vitejs.dev/) ## 🤝 贡献指南 欢迎提交 Issue 和 Pull Request! ### 贡献步骤 1. **Fork** 项目到你的 GitHub 账号 2. **Clone** 分支到本地 3. **创建新分支**开发新功能 4. **提交代码**并推送到远程仓库 5. **创建 Pull Request** ### 开发规范 - 遵循现有代码风格 - 添加必要的注释和文档 - 确保新功能的稳定性和兼容性 - 更新相关测试用例 ## 📞 技术支持 如遇到问题,请提供以下信息: - 插件版本号:`v1.2.9` - uniapp 版本 - Vue 版本 - 错误复现步骤 - 控制台错误信息 - 环境信息(开发/测试/生产) ## 📜 许可证 [ISC License](LICENSE) Copyright (c) 2024 CTC Team --- <div align="center"> <p>✨ 感谢使用 CTC Track Plugin!✨</p> <p>如果这个项目对你有帮助,请给我们一个 ⭐️</p> </div>