一个几乎无感知的前端埋点模块
项目github仓库:https://github.com/darkXmo/bury
项目npm仓库:@xmon/bury
项目gitee仓库:Xmo/bury
如果你的项目埋点会严重影响到业务代码,是时候考虑使用 @xmon/bury 了
除了必要的添加 eventId,即为项目添加 ID 标识的行为以外,@xmon/bury
不会影响到你的业务代码,你只需要添加一下配置就够了!
页面行为埋点,通过事件监听来进行行为监测,目前可以监控事件包括
- 点击事件(Click)
- 页面加载(Load & Unload)
- 特定行为(Action)
- Axios 请求(Api)
- 路由跳转(Router)
# yarn
yarn add @xmon/bury# npm
npm install @xmon/bury# pnpm
pnpm install @xmon/bury
Examples 监听一般事件(开启监听点击、页面加载,特定行为)
// main.js
import { init } from "@xmon/bury";
import config from "./config.js";
const bury = init(config);
配置 你需要在
config
中指定你要监听的路由,路由对应事件(进入和离开)的 eventId
。同时你需要指定埋点的基础参数,他们通常是环境,埋点版本以及系统版本,这些参数都是可选的。
// config.js
import { initUrlMap } from "@xmon/bury";
// 用initUrlMap配置你想要监听的1页面路径和2加载页面,3离开页面的事件ID
initUrlMap([
{
path: "/user/:id",
leave: "eventIdLeavePage", // Leave EventId
enter: "eventIdEnterPage", // Enter EventId
},
]);
// 这里填写埋点事件返回值中的额外字段,通常你需要添加以下几个配置信息
const config = {
environment: process.env.NODE_ENV,
dataPointVersion: "v0.0.1",
version: "1.0.0",
};
export default config;
监听 Router
如果你使用的是
Vue
单页面应用,则还需要监听 Vue-Router
跳转,因此你还需要传入 router
实例作为第 2 个参数import router from "@/router";
// 把router实例注册到bury中
const bury = init(config, router);
监听 Api
如果你需要监听
Axios Api
,则需要封装 Axios
实例。import axios from "axios";
import { trackApi } from "@xmon/bury";
const axiosInstance = axios.create({
...
});
// 提醒 @xmon/bury 监听 axios示例 发出请求的行为
trackApi(axiosInstance);
配置 和页面监听类似,你也需要指定你要监听的
api
路径以及对应的 eventId
。import { initUrlMap, initApiMap } from "@xmon/bury";
initUrlMap([
...
]);
// 利用 initApiMap 来配置需要监听的url
initApiMap([
{
url: "/v3/search/anime",
eventId: "eventIdApi",
},
]);
const config = {
...
};
export default config;
值得注意的是,无论是监听页面加载还是监听监听点击事件api
,都会忽略query
参数。
文章图片
对于需要监听点击事件的元素,添加
data-bupoint
属性,并注入 eventId
即可。监听特定行为
import { track } from "@xmon/bury";
// 对于特定的行为,你需要将行为包装成函数,并配置好eventId,然后再使用track来监听这个函数行为
const increase = track(() => {
console.log("I am tracked");
}, "eventId");
// track的返回值是你传入的函数,原封不动。
// increase = () => { console.log('I am tracked') }
对于行为,你应当使用
track
进行封装,第一个参数是要封装的函数,第二个参数是 eventId
。track
会在封装后返回被封装的函数。埋点行为发生在特定行为执行之前。
触发埋点事件回调 触发监听行为会同时触发埋点行为,通过
onBury
我们可以获取到埋点行为的回调。初始化(
init
)之后才能访问到 instance
、track
、trackApi
、onBury
等方法,否则会抛出未定义错误import { onBury } from "@xmon/bury";
// 做好配置之后,你可以使用 onBury 来监听事件
// 一旦 你配置过的url加载或关闭了 OR 你监听的api请求发送了 OR 你监听的事件被调用了 OR 你观察的Dom被点击了 => 就会触发在 onBury 中注册的回调函数
onBury((value) => {
// 下文中 BuryConfig 中会说明 payload 中包含哪些值
const buryInfo = value.payload;
// 下面是我的埋点回调示例行为,你应当用你的行为代替示例
const queries = Object.entries(buryInfo)
.map(([key, value]) => {
return key + "=" + encodeURI(value);
})
.join("&");
let img = new Image(1, 1);
// 请将url改成你的后端埋点系统的API
img.src = https://www.it610.com/article/`http://exmapleApi.com/bury?` + queries;
// 3000ms超时处理
setTimeout(() => {
if (img && (!img.complete || !img.naturalWidth)) {
img.srchttps://www.it610.com/article/= "";
}
}, 3000);
});
每当被监听的事件发生的时候,都会注册在
onBury
事件中的回调函数。在这个例子中,它将会取出回调参数中的
payload
,并将它封装并发出 img
的 Get
请求。由于API initonBeforeUnload
方法在页面即将关闭时执行,此时无法使用Axios
来发起异步请求。但img
和XMLHttpRequest
同步请求仍然可以执行。
export const init = (config: BuryConfig, router?: VueRouter) => Bury;
// 预配置中的一些配置并没有默认值,可以通过 config 手动添加预设
// 标记为 !!! 的参数是 payload 中预定义的。
// 你也可以自定义参数
export interface BuryConfig {
eventId?: string;
// 必要,事件ID
timestamp?: string;
// !!!
ua?: string;
// !!!
browser?: "MSIE" | "Firefox" | "Safari" | "Chrome" | "Opera";
// !!!
referrer?: string;
// !!!
width?: string;
// !!!
height?: string;
// !!!
ip?: string;
// !!!
cityName?: string;
// !!!
isPhone?: "phone" | "pc";
// !!!
userId?: string;
apiUrl?: string;
pageUrl?: string;
pageStayTime?: string;
project?: string;
environment?: string;
dataPointVersion?: string;
version?: string;
channelCode?: string;
sourceCode?: string;
topCause?: string;
phone?: string;
enterTime?: string;
extraInfo?: string;
[K: string]: string;
}
BuryConfig
中通过 "@fingerprintjs/fingerprintjs"
模块 以及 "http://pv.sohu.com/cityjson?ie=utf-8"
Api
接口获取了一些预设值,它们分别是timestamp
- 时间戳 -new Date().getTime()
ua
- 客户端信息(navigator.userAgent),详情请查看 https://developer.mozilla.org...browser
- 浏览器类型referrer
- 引用来源 - http://www.ruanyifeng.com/blo...width
- 窗口宽度height
- 窗口高度ip
- 客户端 ip 地址cityName
- 客户端省市名 - 如 “江苏省南京市”isPhone
- 是否是移动端,如果是,则值为phone
userId
- 客户端设备的唯一标识符 详情请查阅 https://github.com/fingerprin...
project
、version
、dataPointVersion
、environment
。const bury = init(config, router);
config
预定义参数router
可选参数,如果要监听VueRouter
跳转的话
devtools
的控制台中查看每次触发埋点事件的返回值bury.spy();
initUrlMap 初始化监听的
url
的页面路径及其 eventId
的数组。所有的 eventId 都会被包含在回调函数参数中的 payload 中
interface UrlMap: {
path: string;
// 页面url地址,同VueRouter中的path的定义方式
enter?: string;
// 进入该页面的 EventId
leave?: string;
// 离开该页面的 EventId
}[]
url
页面的url
地址,定义遵循 https://github.com/pillarjs/p... ,通常可以和VueRouter
中的path
参数对照着填。enter
进入该埋点页面的eventId
leave
离开该埋点页面的eventId
关于
path
https://github.com/pillarjs/p...
initApiMap
interface ApiMap: {
url: string;
// 接口的url地址
method?: Method;
// Method ,例如 `GET` `POST` ,如果不定义,则监听该url下的所有 Method
eventId: string;
// 接口被触发时的 EventId
}[] = [];
url
接口的url
地址method
可选参数Method
,例如GET
POST
,如果未定义,则监听该url
下的所有Method
eventId
该埋点接口的eventId
function track any>(fn: T, eventId: string): T;
fn
被埋点的方法eventId
该埋点方法的eventId
trackApi 对
Axios
进行埋点监听function trackApi(axiosInstance: AxiosInstance): void;
onBury 当被埋点的时间触发时的回调函数
function onBury(callback: (value: BuryCallBack) => void): void;
callback
回调函数
interface BuryCallBack {
type: "Action" | "Click" | "Leave" | "Enter" | "Api";
payload: BuryConfig;
extra?:
| Payload.ActionPayload
| Payload.ApiPayload
| Payload.ClickPayload
| Payload.LoadPayload
| Payload.RoutePayload;
}
type
类型 分别是埋点事件、点击、离开页面、载入页面和接口payload
负载,除了预定义的配置以外
Enter
pageUrl
进入的页面url
Leave
PageStayTime
在当前页面停留的时间pageUrl
离开的页面url
Api
apiUrl
接口的url
extra
监听事件的负载,详情请查看 https://github.com/darkXmo/mo...
plugins 在
plugins
文件夹中创建文件 bury.js
或 bury.ts
;
// bury.js
import { init, initUrlMap } from '@xmon/bury';
const bury = init({
version: 'projectVersion',
dataPointVersion: 'v1',
project: 'projectName'
});
initUrlMap([{
path: "/",
enter: "EnterEventPoint",
leave: "LeaveEventPoint"
}, ...])bury.spy();
bury.onBury((value) => {
// do something with value
})
【一个几乎无感知的前端埋点模块】在
nuxt.config.js
或 nuxt.config.ts
中添加插件配置{
plugins: [
...
{ src: "@/plugins/bury.ts", mode: 'client' },
...
],
}
推荐阅读
- 一个人的旅行,三亚
- 一个小故事,我的思考。
- 一个人的碎碎念
- 七年之痒之后
- 我从来不做坏事
- 学无止境,人生还很长
- jhipster|jhipster 升级无效问题
- 异地恋中,逐渐适应一个人到底意味着什么()
- 迷失的世界(二十七)
- live|live to inspire 一个普通上班族的流水账0723