埋点
依赖
npm init
tsc --init
npm install rollup -D
npm install rollup-plugin-dts -D // 生成声明文件
npm install rollup-plugin-typescript2 -D // ts插件支持
npm install typescript -D //
rollup.config.js
import path from 'path'
import ts from 'rollup-plugin-typescript2'
import dts from 'rollup-plugin-dts'
export default [
{
input : './src/core/index.ts' ,
output : [
{
file : path. resolve ( __dirname, './dist/index.esm.js ' ) ,
format : 'es'
} ,
{
file : path. resolve ( __dirname, './dist/index.cjs.js ' ) ,
format : 'cjs'
} ,
{
file : path. resolve ( __dirname, './dist/index.js ' ) ,
format : 'umd' ,
name : 'tracker'
}
] ,
plugins : [
ts ( )
]
} ,
{
input : './src/core/index.ts' ,
output : {
file : path. resolve ( __dirname, './dist/index.d.ts ' ) ,
format : 'es'
} ,
plugins : [
dts ( )
]
}
]
package.json 配置指令(他版本有问题)
{
"name" : "tracker" ,
"version" : "1.0.0" ,
"description" : "" ,
"main" : "index.js" ,
"scripts" : {
"test" : "echo \"Error: no test specified\" && exit 1" ,
"build" : "rollup -c"
} ,
"keywords" : [ ] ,
"author" : "" ,
"license" : "ISC" ,
"devDependencies" : {
"rollup" : "^2.77.0" ,
"rollup-plugin-dts" : "^4.2.2" ,
"rollup-plugin-typescript2" : "^0.32.1" ,
"typescript" : "^4.7.4"
}
}
文件结构
core/ index.ts
import { DefaultOptons, Options, TrackerConfig } from "../type/index" ;
import { creatHistoryEvent } from "../utils/pv" ;
const MouseEventList: string [ ] = [ 'click' , 'dblclick' , 'contextmenu' , 'mousedown' , 'mouseup' , 'mouseenter' , 'mouseout' , 'mouseover' ]
export default class Tracker {
public data: Options;
constructor ( options: Options) {
this . data = Object. assign ( this . initDef ( ) , options)
this . installTracker ( )
}
private installTracker ( ) {
if ( this . data. historyTracker) {
this . ceptureEvents ( [ 'pushState' , 'replaceState' , 'popstate' ] , 'history-pv' )
}
if ( this . data. hashTracker) {
this . ceptureEvents ( [ 'hashchange' ] , 'hash-pv' )
}
if ( this . data. domTracker) {
this . targetKeyReport ( )
}
}
private initDef ( ) : DefaultOptons {
window. history[ 'pushState' ] = creatHistoryEvent ( 'pushState' )
window. history[ 'replaceState' ] = creatHistoryEvent ( 'replaceState' )
return < DefaultOptons> {
historyTracker: false ,
hashTracker: false ,
domTracker: false ,
jsError: false ,
sdkVersion: TrackerConfig. version
}
}
public setUUID < T extends DefaultOptons[ 'uuid' ] > ( uuid: T ) {
this . data. uuid = uuid;
}
public setExtar < T extends DefaultOptons[ 'extra' ] > ( extra: T ) {
this . data. extra = extra
}
public sendTracker < T > ( data: T ) {
this . reportTracker ( data)
}
private ceptureEvents < T > ( mouseEventList: string [ ] , targetKet: string , data? : T ) {
mouseEventList. forEach ( event => {
window. addEventListener ( event, ( e) => {
this . reportTracker ( {
event,
targetKet,
data
} )
} )
} )
}
private reportTracker < T > ( data: T ) {
const params = Object. assign ( this . data, data, { time: new Date ( ) . getTime ( ) } )
let headers = {
type: 'application/x-www-form-urlencoded'
}
let blob = new Blob ( [ JSON . stringify ( params) ] , headers)
navigator. sendBeacon ( this . data. requestUrl, blob)
}
private targetKeyReport ( ) {
MouseEventList. forEach ( key => {
window. addEventListener ( key, ( e) => {
const targer = e. target as HTMLElement
const targetKey = targer. getAttribute ( 'target-ket' )
if ( targetKey) {
this . reportTracker ( {
event: key,
targetKey
} )
}
} )
} )
}
}
type/index.ts
export interface DefaultOptons {
uuid: string | undefined ,
requestUrl: string | undefined ,
historyTracker: boolean ,
hashTracker: boolean ,
domTracker: boolean ,
sdkVersion: string | number ,
extra: Record< string , any > | undefined ,
jsError: boolean
}
export interface Options extends Partial< DefaultOptons> {
requestUrl: string
}
export enum TrackerConfig {
version = '1.0.0'
}
util/pv.ts
export const creatHistoryEvent = < T extends keyof History> ( type: T ) => {
const origin = window. history[ type]
return function ( this : any ) {
const res = origin . apply ( this , arguments)
const e = new Event ( type)
window. dispatchEvent ( e)
return res
}
}