UNPKG

@sdc-monitor/demo

Version:

<div align="center"> <a href="#" target="_blank"> <img src="https://i.loli.net/2021/07/28/EvPwd4NjVH3tBfO.jpg" alt="mito-logo" height="90"> </a> <p>A Lightweight SDK For Monitor Web</p>

205 lines (193 loc) 6.65 kB
import { replaceOld, isEmptyObject } from '@sdc-monitor/utils' import Store from '../core/store' import HandleEvents from './handleEvents' import { WxPerformanceItemType, WxListenerTypes } from '../constant' import { WxPerformanceAnyObj } from '../types/index' export function replaceApp(store: Store) { if (App) { const originApp = App App = function (appOptions: WechatMiniprogram.App.Option) { const methods = Object.keys(HandleEvents).filter((m) => m.indexOf('App') !== -1) methods.forEach((method) => { replaceOld( appOptions, method.replace('AppOn', 'on'), function (originMethod: () => void) { return function (...args: any): void { // 让原本的函数比抛出的hooks先执行,便于埋点判断是否重复 if (originMethod) { originMethod.apply(this, args) } store.emit(method as WxPerformanceItemType, args) } }, true ) }) return originApp(appOptions) } as WechatMiniprogram.App.Constructor } } function replacePageLifeMethods( options: | WechatMiniprogram.Page.Options<WechatMiniprogram.Page.DataOption, WechatMiniprogram.Page.CustomOption> | WechatMiniprogram.Component.MethodOption, store: Store ) { const pageLifeMethods = Object.keys(HandleEvents).filter((m) => m.indexOf('Page') !== -1) pageLifeMethods.forEach((method) => { replaceOld( options, method.replace('PageOn', 'on'), function (originMethod: (args: any) => void) { return function (...args: any[]): void { store.emit(method as WxPerformanceItemType, args) if (originMethod) { return originMethod.apply(this, args) } } }, true ) }) } /** * 监听Page, Component下的点击事件 */ function replaceAction( options: | WechatMiniprogram.Page.Options<WechatMiniprogram.Page.DataOption, WechatMiniprogram.Page.CustomOption> | WechatMiniprogram.Component.MethodOption, store: Store ) { const ListenerTypes = Object.keys(WxListenerTypes) if (options) { Object.keys(options).forEach((m) => { if ('function' !== typeof options[m]) { return } replaceOld( options, m, function (originMethod: (args: any) => void) { return function (...args: any[]): void { const event = args.find((arg) => arg && arg.type && arg.currentTarget) if (event && !event.mitoWorked && ListenerTypes.indexOf(event.type) > -1) { store.emit(WxListenerTypes[event.type] as WxPerformanceItemType, event) event.mitoWorked = true } return originMethod.apply(this, args) } }, true ) }) } } // 重写Page export function replacePage(store: Store) { if (!Page) { return } const originPage = Page Page = function (pageOptions): WechatMiniprogram.Page.Constructor { replacePageLifeMethods(pageOptions, store) replaceAction(pageOptions, store) return originPage.call(this, pageOptions) } } // 重写Component export function replaceComponent(store: Store) { if (!Component) { return } const originComponent = Component // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Component = function (componentOptions): WechatMiniprogram.Component.Constructor { if (!isEmptyObject(componentOptions.methods)) { replacePageLifeMethods(componentOptions.methods, store) replaceAction(componentOptions, store) } return originComponent.call(this, componentOptions) } } // 监听网络性能 export function replaceNetwork(store: Store) { const HOOKS = { request: WxPerformanceItemType.WxRequest, downloadFile: WxPerformanceItemType.WxDownloadFile, uploadFile: WxPerformanceItemType.WxUploadFile } Object.keys(HOOKS).forEach((hook) => { const originRequest = wx[hook] Object.defineProperty(wx, hook, { writable: true, enumerable: true, configurable: true, value: function (...args: any[]) { const options: WechatMiniprogram.RequestOption | WechatMiniprogram.DownloadFileOption | WechatMiniprogram.UploadFileOption = args[0] const { url } = options if (store.filterUrl(url)) { return originRequest.call(this, options) } let reqData = { startTime: Date.now(), header: options.header || {}, url: options.url } as WxPerformanceAnyObj switch (hook) { case 'request': // eslint-disable-next-line no-case-declarations const { method } = options as WechatMiniprogram.RequestOption reqData = { ...reqData, method } break case 'downloadFile': case 'uploadFile': // eslint-disable-next-line no-case-declarations const { filePath } = options as WechatMiniprogram.DownloadFileOption | WechatMiniprogram.UploadFileOption reqData = { ...reqData, filePath, method: hook === 'downloadFile' ? 'GET' : 'POST' } break default: break } const originFail = options.fail const _fail: | WechatMiniprogram.RequestFailCallback | WechatMiniprogram.DownloadFileFailCallback | WechatMiniprogram.UploadFileFailCallback = function (err) { // 系统和网络层面的失败 const endTime = Date.now() reqData.duration = endTime - reqData.startTime reqData.status = 0 reqData.errMsg = err.errMsg reqData.endTime = endTime store.emit(HOOKS[hook], reqData) if (typeof originFail === 'function') { return originFail(err) } } const originSuccess = options.success const _success: | WechatMiniprogram.RequestSuccessCallback | WechatMiniprogram.DownloadFileSuccessCallback | WechatMiniprogram.UploadFileFailCallback = function (res) { const endTime = Date.now() reqData.duration = endTime - reqData.startTime reqData.status = res.statusCode reqData.errMsg = res.errMsg reqData.endTime = endTime store.emit(HOOKS[hook], reqData) if (typeof originSuccess === 'function') { return originSuccess(res) } } return originRequest.call(this, { ...options, success: _success, fail: _fail }) } }) }) }