gio-miniprogram-sdk 4.4.1 → 4.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/alipay.js +1 -1
  2. package/dist/baidu.js +1 -1
  3. package/dist/bytedance.js +1 -1
  4. package/dist/jingdong.js +1 -1
  5. package/dist/kuaishou.js +1 -1
  6. package/dist/plugins/gioABTest.js +1 -1
  7. package/dist/plugins/gioCompress.js +1 -1
  8. package/dist/plugins/gioEventAutoTracking.js +1 -1
  9. package/dist/plugins/gioImpressionTracking.js +1 -1
  10. package/dist/plugins/gioMultipleInstances.js +1 -1
  11. package/dist/plugins/gioPerformance.js +1 -1
  12. package/dist/qq.js +1 -1
  13. package/dist/quickapp.js +1 -1
  14. package/dist/taobao.js +1 -1
  15. package/dist/taro.js +1 -1
  16. package/dist/uniapp.js +1 -1
  17. package/dist/wechat.js +1 -1
  18. package/dist/xiaohongshu.js +1 -1
  19. package/package.json +7 -1
  20. package/.eslintignore +0 -11
  21. package/.eslintrc.js +0 -120
  22. package/.github/workflows/greetings.yml +0 -13
  23. package/.github/workflows/publish.yml +0 -45
  24. package/.prettierignore +0 -19
  25. package/.prettierrc.js +0 -9
  26. package/babel.config.js +0 -6
  27. package/rollup.config.js +0 -100
  28. package/rollup.plugins.config.js +0 -84
  29. package/src/adapters/gioTaobaoAdapter.ts +0 -202
  30. package/src/adapters/gioTaroAdapter.ts +0 -467
  31. package/src/adapters/gioUniAppAdapter.ts +0 -431
  32. package/src/constants/config.ts +0 -170
  33. package/src/constants/emitMsg.ts +0 -24
  34. package/src/constants/regex.ts +0 -18
  35. package/src/core/dataStore/eventContextBuilder.ts +0 -95
  36. package/src/core/dataStore/eventHooks/appEffects.ts +0 -218
  37. package/src/core/dataStore/eventHooks/index.ts +0 -468
  38. package/src/core/dataStore/eventHooks/minipPage.ts +0 -234
  39. package/src/core/dataStore/eventHooks/pageEffects.ts +0 -189
  40. package/src/core/dataStore/index.ts +0 -661
  41. package/src/core/growingIO.ts +0 -637
  42. package/src/core/pluginsInstance/base.ts +0 -157
  43. package/src/core/pluginsInstance/taro.ts +0 -15
  44. package/src/core/pluginsInstance/tb.ts +0 -15
  45. package/src/core/pluginsInstance/uniapp.ts +0 -15
  46. package/src/core/uploader.ts +0 -272
  47. package/src/core/userStore.ts +0 -267
  48. package/src/index.ts +0 -77
  49. package/src/minipInstance/base.ts +0 -352
  50. package/src/minipInstance/framework.ts +0 -24
  51. package/src/minipInstance/jd.ts +0 -11
  52. package/src/minipInstance/ks.ts +0 -12
  53. package/src/minipInstance/my.ts +0 -131
  54. package/src/minipInstance/qq.ts +0 -12
  55. package/src/minipInstance/quickapp.ts +0 -233
  56. package/src/minipInstance/swan.ts +0 -20
  57. package/src/minipInstance/tb.ts +0 -58
  58. package/src/minipInstance/tt.ts +0 -12
  59. package/src/minipInstance/wx.ts +0 -27
  60. package/src/minipInstance/xhs.ts +0 -20
  61. package/src/platformConfig/base.ts +0 -82
  62. package/src/platformConfig/framework.ts +0 -31
  63. package/src/platformConfig/jd.ts +0 -11
  64. package/src/platformConfig/ks.ts +0 -11
  65. package/src/platformConfig/my.ts +0 -16
  66. package/src/platformConfig/qq.ts +0 -13
  67. package/src/platformConfig/quickapp.ts +0 -48
  68. package/src/platformConfig/swan.ts +0 -11
  69. package/src/platformConfig/tb.ts +0 -29
  70. package/src/platformConfig/tt.ts +0 -11
  71. package/src/platformConfig/wx.ts +0 -20
  72. package/src/platformConfig/xhs.ts +0 -27
  73. package/src/plugins/gioABTest.ts +0 -348
  74. package/src/plugins/gioCompress.ts +0 -253
  75. package/src/plugins/gioEventAutoTracking.ts +0 -288
  76. package/src/plugins/gioImpressionTracking.ts +0 -386
  77. package/src/plugins/gioMultipleInstances.ts +0 -189
  78. package/src/plugins/gioPerformance/exception.ts +0 -152
  79. package/src/plugins/gioPerformance/monitor.ts +0 -284
  80. package/src/plugins/gioPerformance/network.ts +0 -197
  81. package/src/plugins/gioPerformance.ts +0 -131
  82. package/src/types/base.ts +0 -167
  83. package/src/types/dataStore.ts +0 -62
  84. package/src/types/eventHooks.ts +0 -147
  85. package/src/types/gioCustomTracking.ts +0 -9
  86. package/src/types/gioEventTracking.ts +0 -10
  87. package/src/types/gioPerformance.ts +0 -8
  88. package/src/types/growingIO.ts +0 -137
  89. package/src/types/minipInstance.ts +0 -133
  90. package/src/types/platforms.ts +0 -64
  91. package/src/types/plugins.ts +0 -24
  92. package/src/types/uploader.ts +0 -30
  93. package/src/types/userStore.ts +0 -28
  94. package/src/utils/glodash.ts +0 -430
  95. package/src/utils/tools.ts +0 -472
  96. package/src/utils/verifiers.ts +0 -52
  97. package/tsconfig.json +0 -32
  98. package/typings/global.d.ts +0 -105
@@ -1,152 +0,0 @@
1
- import { GrowingIOType } from '@@/types/growingIO';
2
- import { isArray, isEmpty, isFunction, toString } from '@@/utils/glodash';
3
- import EMIT_MSG from '@@/constants/emitMsg';
4
-
5
- export default class Exception {
6
- private minipInst: any;
7
- // 监听标记,防止重复监听或者内存泄露
8
- private listenerSet = false;
9
- // 缓存队列,防止SDK初始化之前的报错丢掉或发不出去
10
- private cacheQueue: any[];
11
- private buildErrorEvent: (attributes: any) => void;
12
- constructor(public growingIO: GrowingIOType) {
13
- this.minipInst = this.growingIO.minipInstance.minip;
14
- this.cacheQueue = [];
15
- // 上报方法
16
- this.buildErrorEvent = (attributes: any) =>
17
- this.growingIO.plugins.gioPerformance?.buildPerfEvent(
18
- 'apm_system_error',
19
- attributes
20
- );
21
- // 进入页面时初始化各种错误的监听
22
- this.setListeners();
23
- this.hookNavigate();
24
- // app从后台拉起时开始监听(第一次见进入时会根据listenerSet判断不会重复监听)
25
- if (isFunction(this.minipInst?.onAppShow)) {
26
- this.minipInst?.onAppShow(this.setListeners);
27
- }
28
- // app切后台或关闭小程序时把监听移除,防止内存泄露
29
- if (isFunction(this.minipInst?.onAppHide)) {
30
- this.minipInst?.onAppHide(() => {
31
- if (this.minipInst.canIUse('offError')) {
32
- this.minipInst.offError();
33
- }
34
- if (this.minipInst.canIUse('offUnhandledRejection')) {
35
- this.minipInst.offUnhandledRejection();
36
- }
37
- if (this.minipInst.canIUse('offLazyLoadError')) {
38
- this.minipInst.offLazyLoadError();
39
- }
40
- this.listenerSet = false;
41
- });
42
- }
43
- this.growingIO.emitter.on(EMIT_MSG.SDK_INITIALIZED, () => {
44
- if (!isEmpty(this.cacheQueue)) {
45
- this.cacheQueue.forEach((c: any) => {
46
- this.buildErrorEvent(c);
47
- });
48
- }
49
- });
50
- }
51
-
52
- // 设置错误监听
53
- setListeners = () => {
54
- if (!this.listenerSet) {
55
- // 监听小程序错误事件。如脚本错误或 API 调用报错等。
56
- if (this.minipInst.canIUse('onError')) {
57
- this.minipInst?.onError((errorString: string) => {
58
- this.errorParse(errorString);
59
- });
60
- }
61
- // 监听未处理的 Promise 拒绝事件。
62
- if (this.minipInst.canIUse('onUnhandledRejection')) {
63
- this.minipInst?.onUnhandledRejection((rejectError: any) => {
64
- // 普通的promise reject
65
- if (rejectError.reason.stack) {
66
- this.errorParse(
67
- rejectError.reason.stack,
68
- rejectError.reason.message
69
- );
70
- }
71
- });
72
- }
73
- // 监听异步组件加载失败
74
- if (this.minipInst.canIUse('onLazyLoadError')) {
75
- this.minipInst?.onLazyLoadError((error: any) => {
76
- this.buildErrorEvent({
77
- error_type: error.errMsg,
78
- error_content: toString(error.subpackage)
79
- });
80
- });
81
- }
82
- }
83
- this.listenerSet = true;
84
- };
85
-
86
- // hook跳转方法获取跳转错误
87
- hookNavigate = () => {
88
- const self = this;
89
- [
90
- 'switchTab',
91
- 'reLaunch',
92
- 'redirectTo',
93
- 'navigateTo',
94
- 'navigateBack'
95
- ].forEach((reqKey: string) => {
96
- const originNavigate = this.minipInst[reqKey];
97
- Object.defineProperty(this.minipInst, reqKey, {
98
- writable: true,
99
- enumerable: true,
100
- configurable: true,
101
- value: function (...args: any[]) {
102
- const options: any = args[0] ?? {};
103
- const originFail = options?.fail;
104
- const fail = function (result: any) {
105
- self.growingIO.plugins.gioPerformance?.buildPerfEvent('Error', {
106
- error_type: `${reqKey} Error`,
107
- error_content: result.errMsg
108
- });
109
- if (typeof originFail === 'function') {
110
- return originFail(result);
111
- }
112
- };
113
- return originNavigate.call(this, {
114
- ...options,
115
- fail
116
- });
117
- }
118
- });
119
- });
120
- };
121
-
122
- // 解析普通错误堆栈
123
- errorParse = (errorString: string, msg?: string) => {
124
- // 按分行截取为堆栈数组
125
- const stacks = errorString.split('\n');
126
- let title: string, // 错误标题
127
- content: string; // 错误的第一行堆栈
128
- if (stacks.length) {
129
- stacks.find((v, i) => {
130
- const matcher = v.match(/at (.*?) \((.*):(\d{1,}):(\d{1,})\)/);
131
- if (isArray(matcher)) {
132
- title = stacks[i - 1];
133
- content = v.trim();
134
- return matcher.length;
135
- }
136
- });
137
- if (!title) {
138
- title = stacks[0];
139
- }
140
- if (!content) {
141
- content = stacks[1];
142
- }
143
- } else {
144
- title = msg || 'Error';
145
- content = errorString.substring(0, 100);
146
- }
147
- this.buildErrorEvent({
148
- error_type: msg || title,
149
- error_content: content
150
- });
151
- };
152
- }
@@ -1,284 +0,0 @@
1
- import { PERF_MONITOR_VLUES } from '@@/types/gioPerformance';
2
- import { GrowingIOType } from '@@/types/growingIO';
3
- import { forEach, has, head, isEmpty, keys, unset } from '@@/utils/glodash';
4
- import EMIT_MSG from '@@/constants/emitMsg';
5
-
6
- export default class Monitor {
7
- private minipInst: any;
8
- private appPerf: any;
9
- private pagePerf: any;
10
- private bootType: 'cold' | 'warm';
11
- private lastWarm = false;
12
- public referrerPath = ''; // 基础库低于2.23.1或者taro等一些框架中会没有referrerPageId,因此需要靠自己记录上一个页面
13
- private lastUnloadPath = ''; // 打开小程序后再点击分享的连接进入小程序时,页面会被销毁,会触发页面重新加载,从而变成两个热启动,根据上一个被销毁的页面地址来判断是否要发热启动
14
- private buildMonitorEvent: (attributes: any, extra: any) => void;
15
- constructor(public growingIO: GrowingIOType) {
16
- this.minipInst = this.growingIO.minipInstance.minip;
17
- this.appPerf = {};
18
- this.pagePerf = {};
19
- this.bootType = 'cold';
20
- this.lastWarm = false;
21
- this.buildMonitorEvent = (attributes: any, extra: any) =>
22
- this.growingIO.plugins.gioPerformance?.buildPerfEvent(
23
- 'apm_app_launch',
24
- attributes,
25
- extra
26
- );
27
- // 目前仅微信和字节小程序支持小程序启动性能的获取
28
- if (['MinP', 'bytedance'].includes(this.growingIO.minipInstance.platform)) {
29
- this.initObserver();
30
- }
31
- this.growingIO.emitter.on(
32
- EMIT_MSG.MINIP_LIFECYCLE,
33
- ({ event, timestamp, params }) => {
34
- const [actionType, lifeCycleName] = event.split(' ');
35
- switch (actionType) {
36
- case 'App': {
37
- this.appPerf = {
38
- ...this.appPerf,
39
- [lifeCycleName]: timestamp
40
- };
41
- if (lifeCycleName === 'onShowEnd') {
42
- // 只有靠appOnShow才能判断是不是热启动,所以放在App的生命周期中做标记
43
- // 也因为App的生命周期先执行,在后面Page和Component中判断的时候是没问题的
44
- if (this.bootType === 'warm' && !this.lastWarm) {
45
- this.lastWarm = true;
46
- }
47
- }
48
- break;
49
- }
50
- case 'Page': {
51
- const path = (params.page || params.instance)?.route;
52
- this.pagePerf[path] = {
53
- ...this.pagePerf[path],
54
- [lifeCycleName]: timestamp
55
- };
56
- if (lifeCycleName === 'onShowEnd') {
57
- // 标记当前页面是热启动,则发送App热启动性能
58
- if (
59
- this.lastWarm &&
60
- this.bootType === 'warm' &&
61
- this.referrerPath === path &&
62
- this.lastUnloadPath !== path
63
- ) {
64
- this.handleEvent(path);
65
- }
66
- }
67
- if (['onHide', 'onUnload'].includes(lifeCycleName)) {
68
- this.referrerPath = path;
69
- }
70
- if (lifeCycleName === 'onUnload') {
71
- this.lastUnloadPath = path;
72
- }
73
- break;
74
- }
75
- default:
76
- break;
77
- }
78
- }
79
- );
80
- }
81
-
82
- // 初始化性能监听
83
- initObserver = () => {
84
- const performance = this.minipInst.canIUse('getPerformance')
85
- ? this.minipInst.getPerformance()
86
- : {};
87
- const observer = performance?.createObserver((entryList) => {
88
- this.handleLaunch(head(entryList.getEntriesByName('appLaunch')));
89
- // this.handleScript(head(entryList.getEntriesByName('evaluateScript')));
90
- // this.handleFR(head(entryList.getEntriesByName('firstRender')));
91
- // this.handleFP(head(entryList.getEntriesByName('firstPaint')));
92
- this.handleFCP(head(entryList.getEntriesByName('firstContentfulPaint')));
93
- this.handleLCP(
94
- head(entryList.getEntriesByName('largestContentfulPaint'))
95
- );
96
- this.handleRoute(head(entryList.getEntriesByName('route')));
97
- });
98
- observer?.observe({ entryTypes: ['render', 'script', 'navigation'] });
99
- };
100
-
101
- // 小程序初始化耗时
102
- handleLaunch = (entry: any) => {
103
- if (!isEmpty(entry)) {
104
- this.appPerf = {
105
- ...this.appPerf,
106
- appStartTime: entry.startTime,
107
- appDuration: entry.duration,
108
- firstPath: entry.path
109
- };
110
- }
111
- };
112
-
113
- // 注入代码耗时
114
- // handleScript = (entry: any) => {
115
- // if (!isEmpty(entry)) {
116
- // this.appPerf = {
117
- // ...this.appPerf,
118
- // scriptStartTime: entry.startTime,
119
- // scriptDuration: entry.duration
120
- // };
121
- // }
122
- // };
123
-
124
- // firstRender耗时
125
- // handleFR = (entry: any) => {
126
- // if (!isEmpty(entry)) {
127
- // this.pagePerf[entry.path] = {
128
- // ...this.pagePerf[entry.path],
129
- // FRStartTime: entry.startTime,
130
- // FRDuration: entry.duration,
131
- // };
132
- // }
133
- // };
134
-
135
- // firstPaint耗时
136
- // handleFP = (entry: any) => {
137
- // if (!isEmpty(entry)) {
138
- // this.pagePerf[entry.path] = {
139
- // ...this.pagePerf[entry.path],
140
- // FPStartTime: entry.startTime,
141
- // };
142
- // }
143
- // };
144
-
145
- // firstContentfulPaint耗时
146
- handleFCP = (entry: any) => {
147
- if (!isEmpty(entry)) {
148
- this.pagePerf[entry.path] = {
149
- ...this.pagePerf[entry.path],
150
- FCPStartTime: entry.startTime
151
- };
152
- }
153
- this.entriesValidate(entry ?? { name: 'firstContentfulPaint' });
154
- };
155
-
156
- // largestContentfulPaint耗时
157
- handleLCP = (entry: any) => {
158
- if (!isEmpty(entry)) {
159
- this.pagePerf[entry.path] = {
160
- ...this.pagePerf[entry.path],
161
- LCPStartTime: entry.startTime
162
- };
163
- }
164
- this.entriesValidate(entry ?? { name: 'largestContentfulPaint' });
165
- };
166
-
167
- // 路由跳转耗时
168
- handleRoute = (entry: any) => {
169
- if (!isEmpty(entry)) {
170
- this.pagePerf[entry.path] = {
171
- ...this.pagePerf[entry.path],
172
- navigationStart: entry.startTime,
173
- routeDuration: entry.duration
174
- };
175
- }
176
- this.entriesValidate(entry ?? { name: 'route' });
177
- };
178
-
179
- // 校验指标是否都获取完毕
180
- entriesValidate = (entry: any) => {
181
- const path =
182
- entry.path || this.growingIO.minipInstance.getCurrentPage().route;
183
- if (!this.pagePerf[path]) {
184
- this.pagePerf[path] = {
185
- path
186
- };
187
- }
188
- if (!this.pagePerf[path].entries) {
189
- this.pagePerf[path].entries = [];
190
- }
191
- this.pagePerf[path].entries.push(entry.name);
192
- // 所有的entry都执行过('firstContentfulPaint', 'largestContentfulPaint', 'route')
193
- const matcher = ['firstContentfulPaint', 'largestContentfulPaint', 'route'];
194
- let eve = true;
195
- if (this.pagePerf[path].entries.length < matcher.length) {
196
- eve = false;
197
- }
198
- matcher.forEach((o) => {
199
- if (!this.pagePerf[path].entries.includes(o)) {
200
- eve = false;
201
- }
202
- });
203
- if (eve) {
204
- this.handleEvent(path);
205
- }
206
- };
207
-
208
- // 组装监控事件
209
- handleEvent = (path: string) => {
210
- const { currentPage } = this.growingIO.dataStore.eventHooks;
211
- const perfData: PERF_MONITOR_VLUES = {
212
- // 页面标题
213
- title: currentPage.getPageTitle()
214
- };
215
- const { appStartTime } = this.appPerf;
216
- const appLaunch = this.appPerf.onLaunch;
217
- const appShow = this.appPerf.onShow;
218
- const {
219
- onLoad, // page生命周期
220
- onShowEnd, // page生命周期
221
- onReadyEnd, // page生命周期
222
- navigationStart,
223
- FCPStartTime,
224
- LCPStartTime
225
- } = this.pagePerf[path];
226
- // 用于计算的页面开始时间
227
- const pageStart = onLoad;
228
- // 用于计算的页面结束时间
229
- const pageEnd = onReadyEnd || onShowEnd;
230
- // FCP(白屏时长)从created(相当于页面onLoad)开始算
231
- if (FCPStartTime) {
232
- perfData.first_contentful_paint_duration =
233
- FCPStartTime > pageStart ? FCPStartTime - pageStart : 0;
234
- }
235
- // LCP(最大内容加载时长)从created(相当于页面onLoad)开始算
236
- if (LCPStartTime) {
237
- perfData.largest_contentful_paint_duration =
238
- LCPStartTime > pageStart ? LCPStartTime - pageStart : 0;
239
- }
240
- // 页面加载时长
241
- if (this.referrerPath) {
242
- // 如果上次的页面和本次进入的页面是同一个说明是热启动
243
- if (path === this.referrerPath && appShow) {
244
- // 热启动
245
- perfData.page_launch_duration = pageEnd - appShow;
246
- perfData.reboot_duration = pageEnd - appShow;
247
- perfData.reboot_mode = 'warm';
248
- this.lastWarm = false;
249
- } else {
250
- // 如果上次的页面和本次进入的页面不是同一个说明是跳转页面
251
- perfData.page_launch_duration =
252
- pageEnd - (navigationStart ?? pageStart);
253
- }
254
- } else if (this.bootType === 'cold') {
255
- // 没有上次页面说明是冷启动
256
- perfData.page_launch_duration = pageEnd - appLaunch;
257
- // 如果标记是app首屏页面加载的冷启动,添加app的冷启动标识和冷启动整体加载时长
258
- perfData.reboot_duration = pageEnd - appStartTime;
259
- perfData.reboot_mode = 'cold';
260
- // 如果本次标记了冷启动耗时,则标记后续的小程序启动都是热启动
261
- this.bootType = 'warm';
262
- }
263
- forEach(perfData, (v, k) => {
264
- if ([null, 'null', NaN, 'NaN'].includes(v)) {
265
- unset(perfData, k);
266
- }
267
- });
268
- if (perfData.reboot_mode && !has(perfData, 'reboot_duration')) {
269
- unset(perfData, 'reboot_mode');
270
- }
271
- this.appPerf = {};
272
- this.pagePerf[path] = {};
273
- // 过滤没有性能信息和没有页面加载时长的性能数据
274
- if (keys(perfData).length <= 2 || !has(perfData, 'page_launch_duration')) {
275
- return false;
276
- }
277
- this.buildMonitorEvent(perfData, {
278
- timestamp: +Date.now(),
279
- path: currentPage.getPagePath(),
280
- query: currentPage.getPageQuery(),
281
- title: perfData.title
282
- });
283
- };
284
- }
@@ -1,197 +0,0 @@
1
- import { GrowingIOType } from '@@/types/growingIO';
2
- import {
3
- compact,
4
- forEach,
5
- isArray,
6
- isEmpty,
7
- isNil,
8
- isRegExp,
9
- isString,
10
- unset
11
- } from '@@/utils/glodash';
12
-
13
- export default class Network {
14
- private minipInst: any;
15
- private excludeRegExp: RegExp | string | any[];
16
- private gdpRequestURL: string;
17
- private buildNetworkEvent: (attributes: any) => void;
18
- constructor(public growingIO: GrowingIOType, public options: any = {}) {
19
- this.minipInst = this.growingIO.minipInstance.minip;
20
- this.buildNetworkEvent = (attributes: any) => {
21
- if (!options.network) {
22
- return;
23
- }
24
- const { duration, url, method, statusCode } = attributes;
25
- this.growingIO.plugins.gioPerformance?.buildPerfEvent(
26
- 'apm_network_request',
27
- {
28
- response_duration: duration,
29
- request_address: url,
30
- request_method: method,
31
- http_code: statusCode
32
- }
33
- );
34
- };
35
-
36
- if (this.options.network?.exclude) {
37
- this.excludeRegExp = this.options.network.exclude;
38
- }
39
- this.hookRequest();
40
- // 重写生成地址的方法,sdk在性能分析时需要拿到主实例的请求地址做判断用
41
- const self = this;
42
- const originFunc = this.growingIO.uploader.generateURL;
43
- this.growingIO.uploader.generateURL = function () {
44
- const result = originFunc.apply(this, arguments);
45
- const trackingId = arguments[0];
46
- if (trackingId === self.growingIO.trackingId) {
47
- self.gdpRequestURL = result;
48
- }
49
- return result;
50
- };
51
- }
52
-
53
- // 检验url是否符合过滤条件
54
- verifyUrl = (url: string) => {
55
- // Gio的请求直接过滤
56
- if (url.indexOf(this.gdpRequestURL) > -1) {
57
- return true;
58
- }
59
- // 正则或字符串域名数组过滤
60
- if (isArray(this.excludeRegExp)) {
61
- const verifyResult = compact(
62
- (this.excludeRegExp as any[]).map((re: RegExp | string) => {
63
- if (isRegExp(re)) {
64
- return (re as RegExp).test(url);
65
- } else if (isString(re)) {
66
- return url.indexOf(re as string) > -1;
67
- }
68
- })
69
- );
70
- return !isEmpty(verifyResult);
71
- } else if (isString(this.excludeRegExp)) {
72
- // 单个字符串过滤校验
73
- return url.indexOf(this.excludeRegExp as string) > -1;
74
- } else if (isRegExp(this.excludeRegExp)) {
75
- // 单个正则过滤校验
76
- return (this.excludeRegExp as RegExp).test(url);
77
- } else {
78
- return false;
79
- }
80
- };
81
-
82
- // 重写request
83
- hookRequest = () => {
84
- const self = this;
85
- ['request', 'downloadFile', 'uploadFile'].forEach((reqKey: string) => {
86
- const originRequest = this.minipInst[reqKey];
87
- Object.defineProperty(this.minipInst, reqKey, {
88
- writable: true,
89
- enumerable: true,
90
- configurable: true,
91
- value: function (...args: any[]) {
92
- const options: any = args[0];
93
- const { url } = options;
94
- // 如果符合过滤条件就直接发请求不做处理
95
- if (self.verifyUrl(url)) {
96
- return originRequest.call(this, options);
97
- }
98
- let cstmRequestInfo: any = {
99
- header: options.header || {},
100
- url: options.url
101
- };
102
- switch (reqKey) {
103
- case 'request':
104
- const { method } = options;
105
- cstmRequestInfo = { ...cstmRequestInfo, method };
106
- break;
107
- case 'downloadFile':
108
- case 'uploadFile':
109
- const { filePath } = options;
110
- cstmRequestInfo = {
111
- ...cstmRequestInfo,
112
- filePath,
113
- method: reqKey === 'downloadFile' ? 'GET' : 'POST'
114
- };
115
- break;
116
- default:
117
- break;
118
- }
119
-
120
- const originFail = options.fail;
121
- const fail = function (result: any) {
122
- cstmRequestInfo.endTime = Date.now();
123
- self.growingIO.plugins.gioPerformance?.buildPerfEvent('Error', {
124
- error_type: result.errMsg,
125
- error_content: cstmRequestInfo.url
126
- });
127
- if (typeof originFail === 'function') {
128
- return originFail(result);
129
- }
130
- };
131
-
132
- const originSuccess = options.success;
133
- const success = function (result) {
134
- cstmRequestInfo.endTime = Date.now();
135
- self.networkPerfBuilder(result, cstmRequestInfo);
136
- if (typeof originSuccess === 'function') {
137
- return originSuccess(result);
138
- }
139
- };
140
- cstmRequestInfo.startTime = Date.now();
141
- return originRequest.call(this, {
142
- ...options,
143
- success,
144
- fail
145
- });
146
- }
147
- });
148
- });
149
- };
150
-
151
- // 请求性能数据组装
152
- networkPerfBuilder = (requestResult: any, cstmRequestInfo: any) => {
153
- const { profile = {}, statusCode = 0, errMsg } = requestResult;
154
- const { url, filePath, method } = cstmRequestInfo;
155
- const {
156
- redirectStart,
157
- redirectEnd,
158
- fetchStart,
159
- domainLookUpStart,
160
- domainLookUpEnd,
161
- connectStart,
162
- connectEnd,
163
- requestStart,
164
- responseStart,
165
- responseEnd
166
- } = profile;
167
- const p = !isEmpty(profile);
168
- const networkPerf = {
169
- url,
170
- filePath,
171
- method,
172
- statusCode,
173
- message: errMsg,
174
- // 重定向耗时(重定向没有发生,或者其中一个重定向非同源,则该值为 0)
175
- redirect: p ? redirectEnd - redirectStart : 0,
176
- // 缓存耗时
177
- cache: p ? domainLookUpStart - fetchStart : 0,
178
- // dns域名解析耗时
179
- dns: p ? domainLookUpEnd - domainLookUpStart : 0,
180
- // tcp链接耗时
181
- tcp: p ? connectEnd - connectStart : 0,
182
- // 在SSL链接建立好后,从客户端发送至服务端首次响应的耗时
183
- request: p ? responseStart - requestStart : 0,
184
- // 从服务端首次响应至数据完全响应完的耗时
185
- response: p ? responseEnd - responseStart : 0,
186
- // 请求总耗时
187
- duration: p
188
- ? responseEnd - fetchStart
189
- : cstmRequestInfo.endTime - cstmRequestInfo.startTime
190
- };
191
- forEach(
192
- networkPerf,
193
- (v, k) => (v === '' || isNil(v)) && unset(networkPerf, k)
194
- );
195
- this.buildNetworkEvent(networkPerf);
196
- };
197
- }