ctc-track-plugin
Version:
uniapp 小程序埋点劫持
548 lines (425 loc) • 14.6 kB
Markdown
# CTC Track Plugin
[](https://www.npmjs.com/package/ctc-track-plugin)
[](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)
- [Gitee 仓库](https://gitee.com/kenann/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** 项目到你的 Gitee 账号
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>