gio-miniprogram-sdk 4.0.0 → 4.1.0
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.
- package/dist/alipay.js +1 -1
- package/dist/baidu.js +1 -1
- package/dist/bytedance.js +1 -1
- package/dist/jingdong.js +1 -1
- package/dist/kuaishou.js +1 -1
- package/dist/plugins/gioABTest.js +1 -1
- package/dist/plugins/gioCompress.js +1 -1
- package/dist/plugins/gioEventAutoTracking.js +1 -1
- package/dist/plugins/gioImpressionTracking.js +1 -1
- package/dist/plugins/gioMultipleInstances.js +1 -0
- package/dist/qq.js +1 -1
- package/dist/quickapp.js +1 -1
- package/dist/taobao.js +1 -1
- package/dist/taro.js +1 -1
- package/dist/uniapp.js +1 -1
- package/dist/wechat.js +1 -1
- package/package.json +39 -42
- package/rollup.config.js +11 -6
- package/rollup.plugins.config.js +13 -10
- package/src/{pluginsOut/frameworks → adapters}/gioTaobaoAdapter.ts +47 -44
- package/src/adapters/gioTaroAdapter.ts +459 -0
- package/src/{pluginsOut/frameworks → adapters}/gioUniAppAdapter.ts +35 -6
- package/src/constants/config.ts +49 -20
- package/src/constants/emitMsg.ts +23 -0
- package/src/constants/regex.ts +14 -0
- package/src/core/dataStore/eventContextBuilder.ts +28 -17
- package/src/core/dataStore/eventHooks/appEffects.ts +50 -31
- package/src/core/dataStore/eventHooks/index.ts +7 -5
- package/src/core/dataStore/eventHooks/minipPage.ts +2 -11
- package/src/core/dataStore/eventHooks/pageEffects.ts +61 -27
- package/src/core/dataStore/index.ts +266 -181
- package/src/core/growingIO.ts +312 -179
- package/src/core/pluginsInstance/base.ts +157 -0
- package/src/core/pluginsInstance/taro.ts +15 -0
- package/src/core/pluginsInstance/tb.ts +15 -0
- package/src/core/pluginsInstance/uniapp.ts +15 -0
- package/src/core/uploader.ts +131 -87
- package/src/core/userStore.ts +160 -121
- package/src/index.ts +37 -28
- package/src/minipInstance/base.ts +2 -1
- package/src/minipInstance/quickapp.ts +5 -19
- package/src/platformConfig/base.ts +0 -4
- package/src/{pluginsOut/ordinary → plugins}/gioABTest.ts +74 -37
- package/src/{pluginsOut/ordinary → plugins}/gioEventAutoTracking.ts +25 -18
- package/src/{pluginsOut/ordinary → plugins}/gioImpressionTracking.ts +109 -41
- package/src/plugins/gioMultipleInstances.ts +176 -0
- package/src/types/base.ts +12 -3
- package/src/types/dataStore.ts +31 -16
- package/src/types/eventHooks.ts +8 -9
- package/src/types/growingIO.ts +30 -14
- package/src/types/platforms.ts +0 -4
- package/src/types/plugins.ts +1 -1
- package/src/types/uploader.ts +16 -12
- package/src/types/userStore.ts +21 -17
- package/src/utils/glodash.ts +10 -3
- package/src/utils/tools.ts +27 -6
- package/src/utils/verifiers.ts +25 -50
- package/typings/global.d.ts +5 -0
- package/.babelrc +0 -4
- package/bin/build/full.sh +0 -32
- package/bin/build/jd.sh +0 -14
- package/bin/build/ks.sh +0 -14
- package/bin/build/my.sh +0 -14
- package/bin/build/plugins.sh +0 -5
- package/bin/build/qq.sh +0 -14
- package/bin/build/quickapp.sh +0 -14
- package/bin/build/swan.sh +0 -14
- package/bin/build/taro.sh +0 -18
- package/bin/build/tb.sh +0 -18
- package/bin/build/tt.sh +0 -14
- package/bin/build/uniapp.sh +0 -18
- package/bin/build/wx.sh +0 -14
- package/src/core/plugins.ts +0 -152
- package/src/pluginsOut/README.md +0 -50
- package/src/pluginsOut/frameworks/gioTaroAdapter.ts +0 -358
- package/src/pluginsOut/ordinary/gioCustomTracking.ts +0 -71
- package/bin/{build/all.sh → build.sh} +3 -3
- /package/src/{pluginsOut/ordinary → plugins}/gioCompress.ts +0 -0
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
* 名称:淘宝小程序单发插件
|
|
3
3
|
* 用途:用于提供淘宝小程序云函数和云应用的请求方法。
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { EVENT, EXTEND_EVENT } from '@@/types/base';
|
|
6
6
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
7
|
+
import { head, unset } from '@@/utils/glodash';
|
|
8
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
7
9
|
|
|
8
10
|
let ut;
|
|
9
11
|
class GioTaobaoAdapter {
|
|
10
12
|
constructor(public growingIO: GrowingIOType) {
|
|
11
13
|
const { utils, emitter } = this.growingIO;
|
|
12
14
|
ut = utils;
|
|
13
|
-
emitter.on(
|
|
15
|
+
emitter.on(EMIT_MSG.OPTION_INITIALIZED, (growingIO: GrowingIOType) => {
|
|
14
16
|
const { inPlugin, dataStore } = growingIO;
|
|
15
17
|
if (inPlugin) {
|
|
16
18
|
ut.getGlobal().Component = function (...args: any[]) {
|
|
@@ -18,7 +20,7 @@ class GioTaobaoAdapter {
|
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
22
|
});
|
|
21
|
-
emitter.on(
|
|
23
|
+
emitter.on(EMIT_MSG.MINIP_LIFECYCLE, ({ event }) => {
|
|
22
24
|
const { dataStore, vdsConfig } = this.growingIO;
|
|
23
25
|
const widgetName = `小部件${vdsConfig.appId}`;
|
|
24
26
|
switch (event) {
|
|
@@ -30,10 +32,12 @@ class GioTaobaoAdapter {
|
|
|
30
32
|
.map((k) => `${k}=${relationAppInfo[k]}`)
|
|
31
33
|
.join('&');
|
|
32
34
|
dataStore.scene = sceneInfo.sceneId ?? '';
|
|
33
|
-
dataStore.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
dataStore.trackersExecute((trackingId: string) => {
|
|
36
|
+
dataStore.sendVisit(trackingId, {
|
|
37
|
+
path: widgetName,
|
|
38
|
+
query,
|
|
39
|
+
title: widgetName
|
|
40
|
+
});
|
|
37
41
|
});
|
|
38
42
|
};
|
|
39
43
|
this.getRelationAppInfo((relationAppInfo: any) =>
|
|
@@ -42,9 +46,14 @@ class GioTaobaoAdapter {
|
|
|
42
46
|
}
|
|
43
47
|
break;
|
|
44
48
|
case 'Page didMount':
|
|
45
|
-
dataStore.
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
dataStore.trackersExecute((trackingId: string) => {
|
|
50
|
+
const { trackPage } = dataStore.getTrackerVds(trackingId);
|
|
51
|
+
if (trackPage) {
|
|
52
|
+
dataStore.sendPage(trackingId, {
|
|
53
|
+
path: widgetName,
|
|
54
|
+
title: widgetName
|
|
55
|
+
});
|
|
56
|
+
}
|
|
48
57
|
});
|
|
49
58
|
break;
|
|
50
59
|
default:
|
|
@@ -70,30 +79,31 @@ class GioTaobaoAdapter {
|
|
|
70
79
|
};
|
|
71
80
|
|
|
72
81
|
// 单条发送无延迟
|
|
73
|
-
singleInvoke = () => {
|
|
82
|
+
singleInvoke = (trackingId: string) => {
|
|
74
83
|
const { vdsConfig, emitter, uploader } = this.growingIO;
|
|
84
|
+
const hoardingQueue = uploader.getHoardingQueue(trackingId);
|
|
85
|
+
const requestQueue = uploader.getRequestQueue(trackingId);
|
|
75
86
|
// 过滤掉重试超过3次的请求(直接丢弃)
|
|
76
|
-
uploader.
|
|
77
|
-
(o) => (uploader.retryIds[o.requestId] || 0) < uploader.retryLimit
|
|
78
|
-
);
|
|
79
|
-
uploader.requestQueue = [...uploader.requestQueue].filter(
|
|
87
|
+
uploader.requestQueue[trackingId] = [...requestQueue].filter(
|
|
80
88
|
(o) => (uploader.retryIds[o.requestId] || 0) < uploader.retryLimit
|
|
81
89
|
);
|
|
82
|
-
if (ut.isEmpty([...
|
|
90
|
+
if (ut.isEmpty([...hoardingQueue, ...requestQueue])) {
|
|
83
91
|
return;
|
|
84
92
|
}
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
const eventData: EXTEND_EVENT =
|
|
94
|
+
hoardingQueue.shift() ?? requestQueue.shift();
|
|
95
|
+
let requestData = { ...eventData };
|
|
96
|
+
unset(requestData, ['requestId', 'trackingId']);
|
|
87
97
|
// 开启debug模式时,打印事件日志
|
|
88
98
|
if (vdsConfig.debug) {
|
|
89
99
|
console.log('[GrowingIO Debug]:', JSON.stringify(requestData, null, 2));
|
|
90
100
|
}
|
|
91
|
-
emitter.emit(
|
|
92
|
-
this.cloudFuncInvoke(requestData);
|
|
101
|
+
emitter.emit(EMIT_MSG.ON_SEND_BEFORE, { requestData });
|
|
102
|
+
this.cloudFuncInvoke(eventData, requestData);
|
|
93
103
|
};
|
|
94
104
|
|
|
95
105
|
// 云函数调用
|
|
96
|
-
cloudFuncInvoke = (requestData) => {
|
|
106
|
+
cloudFuncInvoke = (eventData: EXTEND_EVENT, requestData: EVENT) => {
|
|
97
107
|
const { vdsConfig, emitter, uploader } = this.growingIO;
|
|
98
108
|
const { serverUrl, projectId, tbConfig } = vdsConfig;
|
|
99
109
|
const app = ut.niceTry(() => getApp() ?? $global);
|
|
@@ -115,18 +125,18 @@ class GioTaobaoAdapter {
|
|
|
115
125
|
uploader.requestingNum -= 1;
|
|
116
126
|
// 这里的返回值只是调用了api是否成功,真正是否上报成功不知道,要去淘宝控制台看
|
|
117
127
|
if (res.success) {
|
|
118
|
-
emitter.emit(
|
|
128
|
+
emitter.emit(EMIT_MSG.ON_SEND_AFTER, { result: res, requestData });
|
|
119
129
|
} else {
|
|
120
|
-
uploader.requestFailFn(
|
|
130
|
+
uploader.requestFailFn(eventData);
|
|
121
131
|
ut.consoleText(`请求失败! ${JSON.stringify(res)}`, 'error');
|
|
122
132
|
}
|
|
123
|
-
uploader.initiateRequest();
|
|
133
|
+
uploader.initiateRequest(eventData.trackingId);
|
|
124
134
|
})
|
|
125
135
|
.catch((e) => {
|
|
126
136
|
uploader.requestingNum -= 1;
|
|
127
|
-
uploader.requestFailFn(
|
|
137
|
+
uploader.requestFailFn(eventData);
|
|
128
138
|
ut.consoleText(`请求失败! ${JSON.stringify(e)}`, 'error');
|
|
129
|
-
uploader.initiateRequest();
|
|
139
|
+
uploader.initiateRequest(eventData.trackingId);
|
|
130
140
|
});
|
|
131
141
|
} else {
|
|
132
142
|
ut.consoleText(
|
|
@@ -137,12 +147,13 @@ class GioTaobaoAdapter {
|
|
|
137
147
|
};
|
|
138
148
|
|
|
139
149
|
// 云应用调用
|
|
140
|
-
tbCloudAppInvoke(requestData) {
|
|
150
|
+
tbCloudAppInvoke(eventsQueue: EXTEND_EVENT[], requestData: EVENT) {
|
|
141
151
|
const { vdsConfig, emitter, uploader } = this.growingIO;
|
|
142
152
|
const { serverUrl, projectId, tbConfig } = vdsConfig;
|
|
143
153
|
const app = ut.niceTry(() => getApp() ?? $global);
|
|
144
154
|
const cloud = tbConfig.cloud ?? app.cloud;
|
|
145
155
|
if (cloud?.application?.httpRequest) {
|
|
156
|
+
const trackingId = head(eventsQueue).trackingId;
|
|
146
157
|
uploader.requestingNum += 1;
|
|
147
158
|
cloud.application
|
|
148
159
|
.httpRequest({
|
|
@@ -158,30 +169,22 @@ class GioTaobaoAdapter {
|
|
|
158
169
|
uploader.requestingNum -= 1;
|
|
159
170
|
// 这里的返回值只是调用了api是否成功,真正是否上报成功不知道,要看云应用的服务端是不是真的转发成功
|
|
160
171
|
if (res.success) {
|
|
161
|
-
emitter.emit(
|
|
172
|
+
emitter.emit(EMIT_MSG.ON_SEND_AFTER, { result: res, requestData });
|
|
162
173
|
} else {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
} else {
|
|
168
|
-
uploader.requestFailFn(requestData);
|
|
169
|
-
}
|
|
174
|
+
eventsQueue.forEach((o: any) => {
|
|
175
|
+
uploader.requestFailFn(o);
|
|
176
|
+
});
|
|
170
177
|
ut.consoleText(`请求失败! ${JSON.stringify(res)}`, 'error');
|
|
171
178
|
}
|
|
172
|
-
uploader.initiateRequest();
|
|
179
|
+
uploader.initiateRequest(trackingId);
|
|
173
180
|
})
|
|
174
181
|
.catch((e) => {
|
|
175
182
|
uploader.requestingNum -= 1;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
180
|
-
} else {
|
|
181
|
-
uploader.requestFailFn(requestData);
|
|
182
|
-
}
|
|
183
|
+
eventsQueue.forEach((o: any) => {
|
|
184
|
+
uploader.requestFailFn(o);
|
|
185
|
+
});
|
|
183
186
|
ut.consoleText(`请求失败! ${JSON.stringify(e)}`, 'error');
|
|
184
|
-
uploader.initiateRequest();
|
|
187
|
+
uploader.initiateRequest(trackingId);
|
|
185
188
|
});
|
|
186
189
|
} else {
|
|
187
190
|
ut.consoleText(
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 名称:Taro代理插件
|
|
3
|
+
* 用途:用于重写Taro框架下的创建App/Page/Component方法实现代理Hook;并获取Taro框架下的自定义方法真实方法名获取。
|
|
4
|
+
* 注意:测试taro3react时,微信要用react18测试,支付宝要用react17测试。
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
TARO_EVENT_PROPS_REG,
|
|
8
|
+
TARO_EVENT_REACT_FUNC1_REG,
|
|
9
|
+
TARO_EVENT_REACT_FUNC2_REG,
|
|
10
|
+
TARO_EVENT_VUE_FUNC1_REG,
|
|
11
|
+
TARO_EVENT_VUE_FUNC2_REG,
|
|
12
|
+
TARO_EVENT_VUE_FUNC3_REG
|
|
13
|
+
} from '@@/constants/regex';
|
|
14
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
15
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
16
|
+
|
|
17
|
+
let ut;
|
|
18
|
+
const HANDLER = {
|
|
19
|
+
tap: 'onClick',
|
|
20
|
+
longpress: 'onLongPress'
|
|
21
|
+
};
|
|
22
|
+
const CUSTOM_HOOK_EVENTS = [
|
|
23
|
+
'onShareAppMessage',
|
|
24
|
+
'onShareTimeline',
|
|
25
|
+
'onAddToFavorites',
|
|
26
|
+
'onTabItemTap'
|
|
27
|
+
];
|
|
28
|
+
class GioTaroAdapter {
|
|
29
|
+
public taroVersion: string;
|
|
30
|
+
private taro: any;
|
|
31
|
+
private taroVue: any;
|
|
32
|
+
private taroVueVersion: number;
|
|
33
|
+
private exposedNames: any;
|
|
34
|
+
constructor(public growingIO: GrowingIOType) {
|
|
35
|
+
const { utils, emitter, minipInstance } = this.growingIO;
|
|
36
|
+
ut = utils;
|
|
37
|
+
this.exposedNames = {};
|
|
38
|
+
emitter.on(EMIT_MSG.MINIP_LIFECYCLE, ({ event }) => {
|
|
39
|
+
if (['Page onShow', 'Page onReady'].includes(event)) {
|
|
40
|
+
if (this.taro && this.taroVersion === '3') {
|
|
41
|
+
// 提前存储页面节点信息用来获取dataset
|
|
42
|
+
this.saveFullPage(document.body);
|
|
43
|
+
// taro3开发时要等onready才能取到节点,所以补充做一次曝光监听
|
|
44
|
+
setTimeout(
|
|
45
|
+
() => minipInstance.initImpression(minipInstance.getCurrentPage()),
|
|
46
|
+
0
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 主入口,版本判断
|
|
54
|
+
main = () => {
|
|
55
|
+
const { taro, taroVue } = this.growingIO.vdsConfig;
|
|
56
|
+
const { Current, createComponent } = taro;
|
|
57
|
+
const isTaro2 = !Current && createComponent;
|
|
58
|
+
const isTaro3 = Current && !createComponent;
|
|
59
|
+
this.taro = taro;
|
|
60
|
+
if (isTaro2) {
|
|
61
|
+
// taro2
|
|
62
|
+
this.taroVersion = '2';
|
|
63
|
+
this.proxyTaro2(this.taro);
|
|
64
|
+
ut.consoleText('Taro version 2', 'info');
|
|
65
|
+
} else if (isTaro3) {
|
|
66
|
+
// taro3
|
|
67
|
+
this.taroVersion = '3';
|
|
68
|
+
this.taroVue = taroVue;
|
|
69
|
+
if (this.taroVue) {
|
|
70
|
+
const mainVersion = Number(
|
|
71
|
+
ut.head(ut.split(this.taroVue.version, '.'))
|
|
72
|
+
);
|
|
73
|
+
this.taroVueVersion = mainVersion;
|
|
74
|
+
ut.consoleText(`Taro version 3, Vue version ${mainVersion}`, 'info');
|
|
75
|
+
} else {
|
|
76
|
+
ut.consoleText('Taro version 3', 'info');
|
|
77
|
+
}
|
|
78
|
+
this.proxyTaro3();
|
|
79
|
+
} else {
|
|
80
|
+
ut.consoleText('未获取到Taro实例或不支持的Taro版本,请检查!', 'error');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// 代理taro2
|
|
85
|
+
proxyTaro2 = (taro: any) => {
|
|
86
|
+
const self = this;
|
|
87
|
+
const originApp = taro.createApp;
|
|
88
|
+
const originComponent = taro.createComponent;
|
|
89
|
+
if (originApp) {
|
|
90
|
+
taro.createApp = function (AppClass) {
|
|
91
|
+
const AppRef = originApp(AppClass);
|
|
92
|
+
self.growingIO.dataStore.eventHooks.appOverriding(AppRef);
|
|
93
|
+
return AppRef;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (originComponent) {
|
|
97
|
+
taro.createComponent = function (ComponentClass, isPage) {
|
|
98
|
+
const ComponentRef = originComponent(ComponentClass, isPage);
|
|
99
|
+
const targetType = isPage ? 'page' : 'component';
|
|
100
|
+
// wx/qq的生命周期函数和自定义函数都在ComponentRef.methods中
|
|
101
|
+
// my/tt/jd的生命周期函数和自定义函数都在ComponentRef中
|
|
102
|
+
// swan的生命周期函数在ComponentRef.methods中,自定义函数在ComponentRef中
|
|
103
|
+
switch (self.growingIO.gioPlatform) {
|
|
104
|
+
case 'wx':
|
|
105
|
+
case 'qq':
|
|
106
|
+
self.growingIO.dataStore.eventHooks[`${targetType}Overriding`](
|
|
107
|
+
ComponentRef.methods
|
|
108
|
+
);
|
|
109
|
+
break;
|
|
110
|
+
case 'my':
|
|
111
|
+
case 'tt':
|
|
112
|
+
case 'jd':
|
|
113
|
+
self.growingIO.dataStore.eventHooks[`${targetType}Overriding`](
|
|
114
|
+
ComponentRef
|
|
115
|
+
);
|
|
116
|
+
break;
|
|
117
|
+
case 'swan':
|
|
118
|
+
self.growingIO.dataStore.eventHooks[`${targetType}Overriding`](
|
|
119
|
+
ComponentRef
|
|
120
|
+
);
|
|
121
|
+
self.growingIO.dataStore.eventHooks[`${targetType}Overriding`](
|
|
122
|
+
ComponentRef.methods
|
|
123
|
+
);
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
return ComponentRef;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// 代理taro3
|
|
134
|
+
proxyTaro3 = () => {
|
|
135
|
+
const self = this;
|
|
136
|
+
const {
|
|
137
|
+
dataStore: { eventHooks },
|
|
138
|
+
minipInstance
|
|
139
|
+
} = this.growingIO;
|
|
140
|
+
// hook app
|
|
141
|
+
eventHooks.nativeGrowing(['App']);
|
|
142
|
+
// taro3vue2走单独的hook逻辑
|
|
143
|
+
if (this.taroVueVersion === 2) {
|
|
144
|
+
eventHooks.nativeGrowing(['Page']);
|
|
145
|
+
this.taro3Vue2Proxy();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (this.taroVueVersion === 3) {
|
|
149
|
+
this.proxyTaro3vue3();
|
|
150
|
+
}
|
|
151
|
+
// taro3react / taro3vue3走监听hook逻辑
|
|
152
|
+
const originCall = self.taro?.hooks?.call;
|
|
153
|
+
if (originCall) {
|
|
154
|
+
self.defineProperty(self.taro.hooks, 'call', function (...args) {
|
|
155
|
+
const argsArray = Array.from(args);
|
|
156
|
+
let result = originCall.apply(this, argsArray);
|
|
157
|
+
// 根据taro消息直接触发页面生命周期
|
|
158
|
+
if (argsArray[0] === 'getLifecycle') {
|
|
159
|
+
const lifetime = argsArray[2];
|
|
160
|
+
if (
|
|
161
|
+
eventHooks.pageHandlers.includes(lifetime) &&
|
|
162
|
+
!CUSTOM_HOOK_EVENTS.includes(lifetime)
|
|
163
|
+
) {
|
|
164
|
+
ut.niceTry(() =>
|
|
165
|
+
eventHooks.pageEffects.main(
|
|
166
|
+
minipInstance.getCurrentPage(),
|
|
167
|
+
lifetime,
|
|
168
|
+
argsArray[1]
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// 分享和添加收藏事件走hook逻辑
|
|
174
|
+
if (argsArray[0] === 'modifyPageObject') {
|
|
175
|
+
const pageObject = argsArray[1];
|
|
176
|
+
CUSTOM_HOOK_EVENTS.forEach((k) => {
|
|
177
|
+
if (pageObject[k]) {
|
|
178
|
+
pageObject[k] = eventHooks.lifeFcEffects(
|
|
179
|
+
k,
|
|
180
|
+
ut.isFunction(pageObject[k]) ? pageObject[k] : () => {},
|
|
181
|
+
'Page'
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
// 无埋点事件
|
|
187
|
+
if (argsArray[0] === 'dispatchTaroEvent') {
|
|
188
|
+
const taroEvent = argsArray[1];
|
|
189
|
+
const taroElement = argsArray[2];
|
|
190
|
+
const actionEffects =
|
|
191
|
+
self.growingIO.plugins?.gioEventAutoTracking?.main;
|
|
192
|
+
if (
|
|
193
|
+
ut.isFunction(actionEffects) &&
|
|
194
|
+
eventHooks.actionEventTypes.includes(taroEvent.type)
|
|
195
|
+
) {
|
|
196
|
+
const { currentTarget, target, detail } = taroEvent.mpEvent;
|
|
197
|
+
// taro本身会给所有节点添加id,id一致说明是触发事件的节点
|
|
198
|
+
if (target.id === currentTarget.id) {
|
|
199
|
+
// 尝试获取真实的方法名
|
|
200
|
+
try {
|
|
201
|
+
let originHandler = ut.head(
|
|
202
|
+
taroElement.__handlers[taroEvent.type]
|
|
203
|
+
);
|
|
204
|
+
// 一定要有对应的事件
|
|
205
|
+
if (originHandler) {
|
|
206
|
+
if (originHandler.oldHandler) {
|
|
207
|
+
originHandler = originHandler.oldHandler;
|
|
208
|
+
}
|
|
209
|
+
let funcName = '';
|
|
210
|
+
if (self.taroVue) {
|
|
211
|
+
// vue3
|
|
212
|
+
funcName = self.taro3vue3GetFuncName(
|
|
213
|
+
originHandler,
|
|
214
|
+
taroElement
|
|
215
|
+
);
|
|
216
|
+
} else {
|
|
217
|
+
// react --- @tarojs/runtime 3.6.x会有一个随机名的对象存储点击事件优先获取,其他版本直接取originHandler
|
|
218
|
+
funcName = self.taro3reactGetFuncName(
|
|
219
|
+
originHandler,
|
|
220
|
+
taroEvent,
|
|
221
|
+
taroElement
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 构建无埋点事件
|
|
226
|
+
actionEffects(
|
|
227
|
+
{
|
|
228
|
+
...taroEvent.mpEvent,
|
|
229
|
+
currentTarget: {
|
|
230
|
+
...currentTarget,
|
|
231
|
+
detail,
|
|
232
|
+
dataset: {
|
|
233
|
+
...currentTarget.dataset,
|
|
234
|
+
...taroElement.dataset
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
funcName
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
ut.consoleText('Error: ' + error, 'error');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
ut.consoleText('Taro3实例获取失败,请检查初始化逻辑!', 'warn');
|
|
251
|
+
eventHooks.nativeGrowing(['Page']);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// 保存vue3下使用setup写法的function component的导出方法名
|
|
256
|
+
proxyTaro3vue3 = () => {
|
|
257
|
+
const self = this;
|
|
258
|
+
this.taroVue.mixin({
|
|
259
|
+
beforeMount: function () {
|
|
260
|
+
// 存在tid说明是页面
|
|
261
|
+
if (this._?.props?.tid && !ut.isEmpty(this._.exposed)) {
|
|
262
|
+
const path = ut.head(ut.split(this._.props.tid, '?'));
|
|
263
|
+
const kvs = {};
|
|
264
|
+
ut.keys(this._.exposed).forEach((k) => {
|
|
265
|
+
if (this._.exposed[k].name) {
|
|
266
|
+
kvs[this._.exposed[k].name] = k;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
self.exposedNames[path] = { ...kvs };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// taro3react获取方法名
|
|
276
|
+
taro3reactGetFuncName = (
|
|
277
|
+
originHandler: any,
|
|
278
|
+
taroEvent: any,
|
|
279
|
+
taroElement: any
|
|
280
|
+
) => {
|
|
281
|
+
const propsKey = ut
|
|
282
|
+
.keys(taroElement)
|
|
283
|
+
.find((key) => TARO_EVENT_PROPS_REG.test(key));
|
|
284
|
+
const propsHandler =
|
|
285
|
+
ut.niceTry(() => taroElement[propsKey][HANDLER[taroEvent.type]]) ??
|
|
286
|
+
originHandler.oldHandler ??
|
|
287
|
+
originHandler;
|
|
288
|
+
if (propsHandler?.value?.name) {
|
|
289
|
+
return propsHandler?.value?.name;
|
|
290
|
+
} else if (
|
|
291
|
+
propsHandler.name &&
|
|
292
|
+
!['handler', 'invoker'].includes(propsHandler.name)
|
|
293
|
+
) {
|
|
294
|
+
// class component匿名引用方法
|
|
295
|
+
let funcName = ut
|
|
296
|
+
.head(`${propsHandler}`.match(TARO_EVENT_REACT_FUNC1_REG))
|
|
297
|
+
?.replace('return ', '')
|
|
298
|
+
?.replace('(', '');
|
|
299
|
+
if (funcName) {
|
|
300
|
+
return ut.head(ut.drop(ut.split(funcName, '.'))) ?? propsHandler.name;
|
|
301
|
+
} else {
|
|
302
|
+
// component匿名引用方法
|
|
303
|
+
funcName = ut
|
|
304
|
+
.head(`${propsHandler}`.match(TARO_EVENT_REACT_FUNC2_REG))
|
|
305
|
+
?.replace('return ', '')
|
|
306
|
+
?.replace('(', '');
|
|
307
|
+
return funcName ?? propsHandler.name;
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
return this.getAnonymousFunc(taroElement);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// taro3vue3获取方法名
|
|
315
|
+
taro3vue3GetFuncName = (originHandler: any, taroElement: any) => {
|
|
316
|
+
if (ut.startsWith(`${originHandler.value}`.replace(' ', ''), 'function(')) {
|
|
317
|
+
// 使用emit监听组件的方法
|
|
318
|
+
let preFuncName = ut
|
|
319
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC1_REG))
|
|
320
|
+
?.replace('return ', '');
|
|
321
|
+
try {
|
|
322
|
+
// 使用emit监听组件的方法要优先判断
|
|
323
|
+
if (preFuncName) {
|
|
324
|
+
// dev状态时是单引号
|
|
325
|
+
// eslint-disable-next-line
|
|
326
|
+
if (preFuncName.indexOf("'") > -1) {
|
|
327
|
+
// eslint-disable-next-line
|
|
328
|
+
preFuncName = ut.head(ut.drop(ut.split(preFuncName, "'")));
|
|
329
|
+
} else {
|
|
330
|
+
// build状态时是双引号
|
|
331
|
+
preFuncName = ut.head(ut.drop(ut.split(preFuncName, '"')));
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
// 普通引用方法/匿名引用方法/普通setup定义的方法
|
|
335
|
+
preFuncName = ut
|
|
336
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC2_REG))
|
|
337
|
+
?.replace('return ', '');
|
|
338
|
+
// script setup定义且匿名引用的方法(需要配合defineExpose导出,否则是一个编译后的匿名单字母函数名)
|
|
339
|
+
if (!preFuncName) {
|
|
340
|
+
preFuncName = ut
|
|
341
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC3_REG))
|
|
342
|
+
?.replace('return ', '');
|
|
343
|
+
}
|
|
344
|
+
// script setup定义普通引用的方法(需要配合defineExpose导出,否则是一个编译后的匿名单字母函数名)
|
|
345
|
+
if (!preFuncName) {
|
|
346
|
+
preFuncName = originHandler.value?.name;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
preFuncName = '';
|
|
351
|
+
}
|
|
352
|
+
// 能获取到方法名
|
|
353
|
+
if (preFuncName) {
|
|
354
|
+
let funcName =
|
|
355
|
+
preFuncName.indexOf('.') > -1
|
|
356
|
+
? ut.head(ut.drop(ut.split(preFuncName, '.')))
|
|
357
|
+
: preFuncName;
|
|
358
|
+
let path = '';
|
|
359
|
+
if (taroElement?._root?.uid) {
|
|
360
|
+
path = ut.head(ut.split(taroElement._root.uid, '?'));
|
|
361
|
+
} else {
|
|
362
|
+
path = this.growingIO.dataStore.eventHooks.currentPage.path;
|
|
363
|
+
}
|
|
364
|
+
if (this.exposedNames[path]) {
|
|
365
|
+
funcName =
|
|
366
|
+
ut.niceTry(() => this.exposedNames[path][funcName]) ?? funcName;
|
|
367
|
+
}
|
|
368
|
+
return funcName;
|
|
369
|
+
} else {
|
|
370
|
+
// 不能获取方法名,直接构建一个匿名方法名
|
|
371
|
+
return this.getAnonymousFunc(taroElement);
|
|
372
|
+
}
|
|
373
|
+
} else if (originHandler?.value?.name) {
|
|
374
|
+
return originHandler.value.name;
|
|
375
|
+
} else {
|
|
376
|
+
return this.getAnonymousFunc(taroElement);
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// 无法获取的方法名
|
|
381
|
+
getAnonymousFunc = (taroElement: any) => {
|
|
382
|
+
const { path } = this.growingIO.dataStore.eventHooks.currentPage;
|
|
383
|
+
const paths = path.split('/');
|
|
384
|
+
const idx = paths.findIndex((v) => v.indexOf('page') > -1) + 1;
|
|
385
|
+
const pageName = idx && paths[idx] ? paths[idx] : ut.last(paths);
|
|
386
|
+
return `${pageName}_Func${
|
|
387
|
+
ut.startsWith(taroElement.uid, '_')
|
|
388
|
+
? taroElement.uid
|
|
389
|
+
: '_' + taroElement.uid
|
|
390
|
+
}`;
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// taro3使用vue2的代理
|
|
394
|
+
taro3Vue2Proxy = () => {
|
|
395
|
+
const self = this;
|
|
396
|
+
this.taroVue.mixin({
|
|
397
|
+
beforeMount: function () {
|
|
398
|
+
// 对传统methods写法的普通事件hook
|
|
399
|
+
const methods = this.$options.methods;
|
|
400
|
+
ut.keys(methods).forEach((k: string) => {
|
|
401
|
+
self.defineProperty(this, k, self.proxyMethods(k, this[k]));
|
|
402
|
+
});
|
|
403
|
+
// 对setup中定义的事件hook
|
|
404
|
+
const setupState = this._setupState;
|
|
405
|
+
if (!ut.isEmpty(setupState)) {
|
|
406
|
+
ut.keys(setupState).forEach((k: string) => {
|
|
407
|
+
self.defineProperty(
|
|
408
|
+
setupState,
|
|
409
|
+
k,
|
|
410
|
+
self.proxyMethods(k, setupState[k])
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// 重写方法
|
|
419
|
+
proxyMethods = (name: string, method: any) => {
|
|
420
|
+
const { eventHooks } = this.growingIO.dataStore;
|
|
421
|
+
if (ut.isFunction(method) && !eventHooks.pageHandlers.includes(name)) {
|
|
422
|
+
return function (...args) {
|
|
423
|
+
return eventHooks.customFcEffects(name, method).apply(this, args);
|
|
424
|
+
};
|
|
425
|
+
} else {
|
|
426
|
+
return method;
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
// 重新定义属性
|
|
431
|
+
defineProperty = (target, key, value) => {
|
|
432
|
+
Object.defineProperty(target, key, {
|
|
433
|
+
writable: true,
|
|
434
|
+
enumerable: true,
|
|
435
|
+
configurable: true,
|
|
436
|
+
value
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
// taro3中存储当前页面完整的数据以获取曝光事件中的dataset
|
|
441
|
+
// https://taro-docs.jd.com/taro/docs/react-overall#dataset
|
|
442
|
+
saveFullPage = (body: any) => {
|
|
443
|
+
const pageTraverse = (tEle: any) => {
|
|
444
|
+
tEle.forEach((cEle: any) => {
|
|
445
|
+
if (cEle?.ctx?.route) {
|
|
446
|
+
if (!this.growingIO.taro3VMs) {
|
|
447
|
+
this.growingIO.taro3VMs = {};
|
|
448
|
+
}
|
|
449
|
+
this.growingIO.taro3VMs[cEle.ctx.route] = cEle;
|
|
450
|
+
} else if (ut.isArray(cEle.childNodes)) {
|
|
451
|
+
pageTraverse(cEle.childNodes);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
};
|
|
455
|
+
pageTraverse(body.childNodes);
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export default { name: 'gioTaroAdapter', method: GioTaroAdapter };
|