@haluo/util 2.0.27 → 2.0.29
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/README.md +350 -350
- package/dist/index.d.ts +39 -39
- package/dist/index.js +43 -43
- package/dist/modules/cookie/index.d.ts +27 -27
- package/dist/modules/cookie/index.js +49 -49
- package/dist/modules/date/index.d.ts +52 -52
- package/dist/modules/date/index.js +185 -185
- package/dist/modules/dom/index.d.ts +28 -28
- package/dist/modules/dom/index.js +55 -55
- package/dist/modules/filter/index.d.ts +24 -24
- package/dist/modules/filter/index.js +38 -38
- package/dist/modules/format/index.d.ts +15 -15
- package/dist/modules/format/index.js +16 -16
- package/dist/modules/match/index.d.ts +12 -12
- package/dist/modules/match/index.js +27 -27
- package/dist/modules/monitor/index.d.ts +3 -3
- package/dist/modules/monitor/index.js +10 -10
- package/dist/modules/monitor/lib/jsError.d.ts +1 -1
- package/dist/modules/monitor/lib/jsError.js +57 -57
- package/dist/modules/monitor/lib/timing.d.ts +1 -1
- package/dist/modules/monitor/lib/timing.js +65 -65
- package/dist/modules/monitor/lib/xhr.d.ts +1 -1
- package/dist/modules/monitor/lib/xhr.js +41 -41
- package/dist/modules/monitor/utils/onload.d.ts +1 -1
- package/dist/modules/monitor/utils/onload.js +8 -8
- package/dist/modules/monitor/utils/tracker.d.ts +7 -7
- package/dist/modules/monitor/utils/tracker.js +49 -49
- package/dist/modules/number/index.d.ts +47 -47
- package/dist/modules/number/index.js +114 -114
- package/dist/modules/open-app/index.d.ts +84 -84
- package/dist/modules/open-app/index.js +244 -244
- package/dist/modules/sentry/index.d.ts +15 -15
- package/dist/modules/sentry/index.js +73 -73
- package/dist/modules/tools/index.d.ts +166 -166
- package/dist/modules/tools/index.js +382 -382
- package/dist/modules/upload/aliOss.d.ts +291 -291
- package/dist/modules/upload/aliOss.js +629 -626
- package/dist/modules/upload/index.d.ts +38 -39
- package/dist/modules/upload/index.js +44 -45
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +1 -1
- package/dist/types/modules/cookie/index.d.ts +27 -0
- package/dist/types/modules/date/index.d.ts +52 -0
- package/dist/types/modules/dom/index.d.ts +28 -0
- package/dist/types/modules/filter/index.d.ts +24 -0
- package/dist/types/modules/format/index.d.ts +15 -0
- package/dist/types/modules/match/index.d.ts +12 -0
- package/dist/types/modules/monitor/index.d.ts +3 -0
- package/dist/types/modules/monitor/lib/jsError.d.ts +1 -0
- package/dist/types/modules/monitor/lib/timing.d.ts +1 -0
- package/dist/types/modules/monitor/lib/xhr.d.ts +1 -0
- package/dist/types/modules/monitor/utils/onload.d.ts +1 -0
- package/dist/types/modules/monitor/utils/tracker.d.ts +7 -0
- package/dist/types/modules/number/index.d.ts +41 -0
- package/dist/types/modules/sentry/index.d.ts +15 -0
- package/dist/types/modules/tools/index.d.ts +166 -0
- package/dist/types/types/index.d.ts +3 -0
- package/package.json +88 -88
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file 过滤器
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
* @createBy: @2020.05.28
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
import dateClass from '../date';
|
|
8
|
-
import numberClass from '../number';
|
|
9
|
-
import toolsClass from '../tools';
|
|
10
|
-
class FilterClass {
|
|
11
|
-
/**
|
|
12
|
-
* 格式化时间,示例:1586840260500 | format('YYYY-MM-DD HH:mm:ss')
|
|
13
|
-
* @param {String|Number} date
|
|
14
|
-
* @param {String} fmt 'YYYY-MM-DD HH:mm:ss'
|
|
15
|
-
* @return {String} 'YYYY-MM-DD HH:mm:ss'
|
|
16
|
-
*/
|
|
17
|
-
format(date, fmt = 'YYYY-MM-DD HH:mm:ss') {
|
|
18
|
-
return dateClass.format(date, fmt);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* 格式化金额,示例:123456 | formatMoney
|
|
22
|
-
* @param {Number} num
|
|
23
|
-
* @return {String} 123,456
|
|
24
|
-
*/
|
|
25
|
-
formatMoney(money) {
|
|
26
|
-
return numberClass.formatMoney(money);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 截取数组或字符串,示例:'1234' | slice(3)
|
|
30
|
-
* @param {Array|String} target 数组或字符串
|
|
31
|
-
* @param {Number} length 截取长度,从0开始
|
|
32
|
-
* @return {any}
|
|
33
|
-
*/
|
|
34
|
-
slice(target = '', length = 0) {
|
|
35
|
-
return toolsClass.slice(target, length);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export default new FilterClass();
|
|
1
|
+
/**
|
|
2
|
+
* @file 过滤器
|
|
3
|
+
* @Author: wanghui
|
|
4
|
+
* @createBy: @2020.05.28
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
import dateClass from '../date';
|
|
8
|
+
import numberClass from '../number';
|
|
9
|
+
import toolsClass from '../tools';
|
|
10
|
+
class FilterClass {
|
|
11
|
+
/**
|
|
12
|
+
* 格式化时间,示例:1586840260500 | format('YYYY-MM-DD HH:mm:ss')
|
|
13
|
+
* @param {String|Number} date
|
|
14
|
+
* @param {String} fmt 'YYYY-MM-DD HH:mm:ss'
|
|
15
|
+
* @return {String} 'YYYY-MM-DD HH:mm:ss'
|
|
16
|
+
*/
|
|
17
|
+
format(date, fmt = 'YYYY-MM-DD HH:mm:ss') {
|
|
18
|
+
return dateClass.format(date, fmt);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 格式化金额,示例:123456 | formatMoney
|
|
22
|
+
* @param {Number} num
|
|
23
|
+
* @return {String} 123,456
|
|
24
|
+
*/
|
|
25
|
+
formatMoney(money) {
|
|
26
|
+
return numberClass.formatMoney(money);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 截取数组或字符串,示例:'1234' | slice(3)
|
|
30
|
+
* @param {Array|String} target 数组或字符串
|
|
31
|
+
* @param {Number} length 截取长度,从0开始
|
|
32
|
+
* @return {any}
|
|
33
|
+
*/
|
|
34
|
+
slice(target = '', length = 0) {
|
|
35
|
+
return toolsClass.slice(target, length);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export default new FilterClass();
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
interface Obj {
|
|
2
|
-
[prop: string]: any;
|
|
3
|
-
}
|
|
4
|
-
declare class Format {
|
|
5
|
-
/**
|
|
6
|
-
* @desc 对于对象非数字与布尔值的value,当其为falsy时,转换成separator
|
|
7
|
-
* @param {object} obj 传入的对象
|
|
8
|
-
* @param {string} separator 替换后的值
|
|
9
|
-
* transformObjectNullVal({ a: null, b: 0}, '23') // {a: "23", b: 0}
|
|
10
|
-
* @return {object}
|
|
11
|
-
*/
|
|
12
|
-
transformObjectNullVal<T extends Obj>(obj: T, separator?: string): T;
|
|
13
|
-
}
|
|
14
|
-
declare const _default: Format;
|
|
15
|
-
export default _default;
|
|
1
|
+
interface Obj {
|
|
2
|
+
[prop: string]: any;
|
|
3
|
+
}
|
|
4
|
+
declare class Format {
|
|
5
|
+
/**
|
|
6
|
+
* @desc 对于对象非数字与布尔值的value,当其为falsy时,转换成separator
|
|
7
|
+
* @param {object} obj 传入的对象
|
|
8
|
+
* @param {string} separator 替换后的值
|
|
9
|
+
* transformObjectNullVal({ a: null, b: 0}, '23') // {a: "23", b: 0}
|
|
10
|
+
* @return {object}
|
|
11
|
+
*/
|
|
12
|
+
transformObjectNullVal<T extends Obj>(obj: T, separator?: string): T;
|
|
13
|
+
}
|
|
14
|
+
declare const _default: Format;
|
|
15
|
+
export default _default;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
class Format {
|
|
2
|
-
/**
|
|
3
|
-
* @desc 对于对象非数字与布尔值的value,当其为falsy时,转换成separator
|
|
4
|
-
* @param {object} obj 传入的对象
|
|
5
|
-
* @param {string} separator 替换后的值
|
|
6
|
-
* transformObjectNullVal({ a: null, b: 0}, '23') // {a: "23", b: 0}
|
|
7
|
-
* @return {object}
|
|
8
|
-
*/
|
|
9
|
-
transformObjectNullVal(obj, separator = '-') {
|
|
10
|
-
return Object.keys(obj).reduce((cur, key) => {
|
|
11
|
-
cur[key] = obj[key] || ((obj[key] === 0 || obj[key] === false) ? obj[key] : separator);
|
|
12
|
-
return cur;
|
|
13
|
-
}, {});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export default new Format();
|
|
1
|
+
class Format {
|
|
2
|
+
/**
|
|
3
|
+
* @desc 对于对象非数字与布尔值的value,当其为falsy时,转换成separator
|
|
4
|
+
* @param {object} obj 传入的对象
|
|
5
|
+
* @param {string} separator 替换后的值
|
|
6
|
+
* transformObjectNullVal({ a: null, b: 0}, '23') // {a: "23", b: 0}
|
|
7
|
+
* @return {object}
|
|
8
|
+
*/
|
|
9
|
+
transformObjectNullVal(obj, separator = '-') {
|
|
10
|
+
return Object.keys(obj).reduce((cur, key) => {
|
|
11
|
+
cur[key] = obj[key] || ((obj[key] === 0 || obj[key] === false) ? obj[key] : separator);
|
|
12
|
+
return cur;
|
|
13
|
+
}, {});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export default new Format();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
declare class MatchClass {
|
|
2
|
-
/**
|
|
3
|
-
* 根据类型返回正则
|
|
4
|
-
* @param {String} str 检测的内容
|
|
5
|
-
* @param {String} type 检测类型
|
|
6
|
-
* checkType('10.120.33.11', 'ip') // true
|
|
7
|
-
* @return {Boolean} true or false
|
|
8
|
-
*/
|
|
9
|
-
checkType(str: string, type: string): boolean;
|
|
10
|
-
}
|
|
11
|
-
declare const _default: MatchClass;
|
|
12
|
-
export default _default;
|
|
1
|
+
declare class MatchClass {
|
|
2
|
+
/**
|
|
3
|
+
* 根据类型返回正则
|
|
4
|
+
* @param {String} str 检测的内容
|
|
5
|
+
* @param {String} type 检测类型
|
|
6
|
+
* checkType('10.120.33.11', 'ip') // true
|
|
7
|
+
* @return {Boolean} true or false
|
|
8
|
+
*/
|
|
9
|
+
checkType(str: string, type: string): boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const _default: MatchClass;
|
|
12
|
+
export default _default;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file: tools 常用的工具函数
|
|
3
|
-
* @Author: wanghui
|
|
4
|
-
*/
|
|
5
|
-
'use strict';
|
|
6
|
-
class MatchClass {
|
|
7
|
-
/**
|
|
8
|
-
* 根据类型返回正则
|
|
9
|
-
* @param {String} str 检测的内容
|
|
10
|
-
* @param {String} type 检测类型
|
|
11
|
-
* checkType('10.120.33.11', 'ip') // true
|
|
12
|
-
* @return {Boolean} true or false
|
|
13
|
-
*/
|
|
14
|
-
checkType(str, type) {
|
|
15
|
-
const regexp = {
|
|
16
|
-
'ip': /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/.test(str),
|
|
17
|
-
'port': /^(\d|[1-5]\d{4}|6[1-4]\d{3}|65[1-4]\d{2}|655[1-2]\d|6553[1-5])$/.test(str),
|
|
18
|
-
'phone': /^1[3|4|5|6|7|8][0-9]{9}$/.test(str),
|
|
19
|
-
'number': /^[0-9]+$/.test(str),
|
|
20
|
-
'email': /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(str),
|
|
21
|
-
'IDCard': /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(str),
|
|
22
|
-
'url': /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str)
|
|
23
|
-
};
|
|
24
|
-
return regexp[type];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export default new MatchClass();
|
|
1
|
+
/**
|
|
2
|
+
* @file: tools 常用的工具函数
|
|
3
|
+
* @Author: wanghui
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
class MatchClass {
|
|
7
|
+
/**
|
|
8
|
+
* 根据类型返回正则
|
|
9
|
+
* @param {String} str 检测的内容
|
|
10
|
+
* @param {String} type 检测类型
|
|
11
|
+
* checkType('10.120.33.11', 'ip') // true
|
|
12
|
+
* @return {Boolean} true or false
|
|
13
|
+
*/
|
|
14
|
+
checkType(str, type) {
|
|
15
|
+
const regexp = {
|
|
16
|
+
'ip': /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/.test(str),
|
|
17
|
+
'port': /^(\d|[1-5]\d{4}|6[1-4]\d{3}|65[1-4]\d{2}|655[1-2]\d|6553[1-5])$/.test(str),
|
|
18
|
+
'phone': /^1[3|4|5|6|7|8][0-9]{9}$/.test(str),
|
|
19
|
+
'number': /^[0-9]+$/.test(str),
|
|
20
|
+
'email': /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(str),
|
|
21
|
+
'IDCard': /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(str),
|
|
22
|
+
'url': /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str)
|
|
23
|
+
};
|
|
24
|
+
return regexp[type];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export default new MatchClass();
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import Tracker from './utils/tracker';
|
|
2
|
-
export default function setup(data: any): void;
|
|
3
|
-
export { Tracker };
|
|
1
|
+
import Tracker from './utils/tracker';
|
|
2
|
+
export default function setup(data: any): void;
|
|
3
|
+
export { Tracker };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { injectJsError } from './lib/jsError';
|
|
2
|
-
import injectXhrError from './lib/xhr';
|
|
3
|
-
import Tracker from './utils/tracker';
|
|
4
|
-
// import timing from './lib/timing'
|
|
5
|
-
export default function setup(data) {
|
|
6
|
-
injectJsError(data);
|
|
7
|
-
injectXhrError(data);
|
|
8
|
-
}
|
|
9
|
-
export { Tracker };
|
|
10
|
-
// timing()
|
|
1
|
+
import { injectJsError } from './lib/jsError';
|
|
2
|
+
import injectXhrError from './lib/xhr';
|
|
3
|
+
import Tracker from './utils/tracker';
|
|
4
|
+
// import timing from './lib/timing'
|
|
5
|
+
export default function setup(data) {
|
|
6
|
+
injectJsError(data);
|
|
7
|
+
injectXhrError(data);
|
|
8
|
+
}
|
|
9
|
+
export { Tracker };
|
|
10
|
+
// timing()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function injectJsError(data?: any): void;
|
|
1
|
+
export declare function injectJsError(data?: any): void;
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import track from '../utils/tracker';
|
|
2
|
-
export function injectJsError(data = {}) {
|
|
3
|
-
window.addEventListener('error', (e) => {
|
|
4
|
-
if (e.target && (e.target.src || e.target.href)) {
|
|
5
|
-
track.send({
|
|
6
|
-
kind: 'stability',
|
|
7
|
-
type: 'error',
|
|
8
|
-
title: 'resourceError',
|
|
9
|
-
filename: e.target.src || e.target.href,
|
|
10
|
-
tagName: e.target.tagName,
|
|
11
|
-
reason: e.target.src || e.target.href,
|
|
12
|
-
...data
|
|
13
|
-
// selector: lastEvent ? get
|
|
14
|
-
});
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
track.send({
|
|
18
|
-
kind: 'stability',
|
|
19
|
-
type: 'error',
|
|
20
|
-
title: 'jsError',
|
|
21
|
-
message: e.message,
|
|
22
|
-
filename: e.filename,
|
|
23
|
-
position: `${e.lineno}:${e.colno}`,
|
|
24
|
-
reason: e.error.stack,
|
|
25
|
-
...data
|
|
26
|
-
// selector: lastEvent ? get
|
|
27
|
-
});
|
|
28
|
-
}, true);
|
|
29
|
-
window.addEventListener('unhandledrejection', (e) => {
|
|
30
|
-
let message, filename, line, column, stack;
|
|
31
|
-
const reason = e.reason;
|
|
32
|
-
if (typeof reason === 'string') {
|
|
33
|
-
message = reason;
|
|
34
|
-
}
|
|
35
|
-
else if (typeof reason === 'object') {
|
|
36
|
-
if (reason.stack) {
|
|
37
|
-
const matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
|
|
38
|
-
filename = matchResult[1];
|
|
39
|
-
line = matchResult[2];
|
|
40
|
-
column = matchResult[3];
|
|
41
|
-
}
|
|
42
|
-
message = reason.message;
|
|
43
|
-
stack = reason.stack;
|
|
44
|
-
}
|
|
45
|
-
track.send({
|
|
46
|
-
kind: 'stability',
|
|
47
|
-
type: 'error',
|
|
48
|
-
title: 'promiseError',
|
|
49
|
-
message,
|
|
50
|
-
filename,
|
|
51
|
-
position: `${line}:${column}`,
|
|
52
|
-
reason: stack,
|
|
53
|
-
...data
|
|
54
|
-
// selector: lastEvent ? get
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
}
|
|
1
|
+
import track from '../utils/tracker';
|
|
2
|
+
export function injectJsError(data = {}) {
|
|
3
|
+
window.addEventListener('error', (e) => {
|
|
4
|
+
if (e.target && (e.target.src || e.target.href)) {
|
|
5
|
+
track.send({
|
|
6
|
+
kind: 'stability',
|
|
7
|
+
type: 'error',
|
|
8
|
+
title: 'resourceError',
|
|
9
|
+
filename: e.target.src || e.target.href,
|
|
10
|
+
tagName: e.target.tagName,
|
|
11
|
+
reason: e.target.src || e.target.href,
|
|
12
|
+
...data
|
|
13
|
+
// selector: lastEvent ? get
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
track.send({
|
|
18
|
+
kind: 'stability',
|
|
19
|
+
type: 'error',
|
|
20
|
+
title: 'jsError',
|
|
21
|
+
message: e.message,
|
|
22
|
+
filename: e.filename,
|
|
23
|
+
position: `${e.lineno}:${e.colno}`,
|
|
24
|
+
reason: e.error.stack,
|
|
25
|
+
...data
|
|
26
|
+
// selector: lastEvent ? get
|
|
27
|
+
});
|
|
28
|
+
}, true);
|
|
29
|
+
window.addEventListener('unhandledrejection', (e) => {
|
|
30
|
+
let message, filename, line, column, stack;
|
|
31
|
+
const reason = e.reason;
|
|
32
|
+
if (typeof reason === 'string') {
|
|
33
|
+
message = reason;
|
|
34
|
+
}
|
|
35
|
+
else if (typeof reason === 'object') {
|
|
36
|
+
if (reason.stack) {
|
|
37
|
+
const matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
|
|
38
|
+
filename = matchResult[1];
|
|
39
|
+
line = matchResult[2];
|
|
40
|
+
column = matchResult[3];
|
|
41
|
+
}
|
|
42
|
+
message = reason.message;
|
|
43
|
+
stack = reason.stack;
|
|
44
|
+
}
|
|
45
|
+
track.send({
|
|
46
|
+
kind: 'stability',
|
|
47
|
+
type: 'error',
|
|
48
|
+
title: 'promiseError',
|
|
49
|
+
message,
|
|
50
|
+
filename,
|
|
51
|
+
position: `${line}:${column}`,
|
|
52
|
+
reason: stack,
|
|
53
|
+
...data
|
|
54
|
+
// selector: lastEvent ? get
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function timing(): void;
|
|
1
|
+
export default function timing(): void;
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
import onload from '../utils/onload';
|
|
2
|
-
import tracker from '../utils/tracker';
|
|
3
|
-
export default function timing() {
|
|
4
|
-
let FMP, LCP;
|
|
5
|
-
new PerformanceObserver((entryList, observer) => {
|
|
6
|
-
const perfEntries = entryList.getEntries();
|
|
7
|
-
FMP = perfEntries[0];
|
|
8
|
-
observer.disconnect(); // 不再观察
|
|
9
|
-
}).observe({ entryTypes: ['element'] }); // 观察页面中有意义的元素
|
|
10
|
-
new PerformanceObserver((entryList, observer) => {
|
|
11
|
-
const perfEntries = entryList.getEntries();
|
|
12
|
-
LCP = perfEntries[0];
|
|
13
|
-
observer.disconnect(); // 不再观察
|
|
14
|
-
}).observe({ entryTypes: ['largest-contentful-paint'] }); // 观察页面中最大的元素
|
|
15
|
-
new PerformanceObserver((entryList, observer) => {
|
|
16
|
-
const firstInput = entryList.getEntries();
|
|
17
|
-
console.log('FID', firstInput);
|
|
18
|
-
if (firstInput) {
|
|
19
|
-
let inputDelay = firstInput.processingStart - firstInput.startTime;
|
|
20
|
-
const duration = firstInput.duration;
|
|
21
|
-
if (inputDelay > 0 || duration > 0) {
|
|
22
|
-
tracker.send({
|
|
23
|
-
kind: 'experience',
|
|
24
|
-
type: 'firstInputDelay',
|
|
25
|
-
inputDelay,
|
|
26
|
-
duration,
|
|
27
|
-
startTime: firstInput.startTime
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
observer.disconnect(); // 不再观察
|
|
32
|
-
}).observe({ type: 'first-input', buffered: true }); // 观察页面中最大的元素
|
|
33
|
-
onload(function () {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
console.dir(window.performance);
|
|
36
|
-
const { fetchStart, connectStart, connectEnd, requestStart, responseStart, responseEnd, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, loadEventStart,
|
|
37
|
-
// loadEventEnd
|
|
38
|
-
} = performance.getEntriesByType('navigation')[0];
|
|
39
|
-
tracker.send({
|
|
40
|
-
kind: 'experience',
|
|
41
|
-
type: 'timing',
|
|
42
|
-
connectTime: connectEnd - connectStart,
|
|
43
|
-
ttfbTime: responseStart - requestStart,
|
|
44
|
-
responseTime: responseEnd - responseStart,
|
|
45
|
-
domContentLoadedTime: domContentLoadedEventEnd - domContentLoadedEventStart,
|
|
46
|
-
timeToInteractive: domInteractive - fetchStart,
|
|
47
|
-
loadTime: loadEventStart - fetchStart // 完整的页面加载时间
|
|
48
|
-
});
|
|
49
|
-
let FP = performance.getEntriesByName('first-paint')[0];
|
|
50
|
-
let FCP = performance.getEntriesByName('first-contentful-paint')[0];
|
|
51
|
-
console.log('FP', FP);
|
|
52
|
-
console.log('FCP', FCP);
|
|
53
|
-
console.log('FMP', FMP);
|
|
54
|
-
console.log('LCP', LCP);
|
|
55
|
-
tracker.send({
|
|
56
|
-
kind: 'experience',
|
|
57
|
-
type: 'paint',
|
|
58
|
-
FP: FP.startTime,
|
|
59
|
-
FCP: FCP.startTime,
|
|
60
|
-
FMP: FMP.startTime,
|
|
61
|
-
LCP: LCP.startTime,
|
|
62
|
-
});
|
|
63
|
-
}, 3000);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
1
|
+
import onload from '../utils/onload';
|
|
2
|
+
import tracker from '../utils/tracker';
|
|
3
|
+
export default function timing() {
|
|
4
|
+
let FMP, LCP;
|
|
5
|
+
new PerformanceObserver((entryList, observer) => {
|
|
6
|
+
const perfEntries = entryList.getEntries();
|
|
7
|
+
FMP = perfEntries[0];
|
|
8
|
+
observer.disconnect(); // 不再观察
|
|
9
|
+
}).observe({ entryTypes: ['element'] }); // 观察页面中有意义的元素
|
|
10
|
+
new PerformanceObserver((entryList, observer) => {
|
|
11
|
+
const perfEntries = entryList.getEntries();
|
|
12
|
+
LCP = perfEntries[0];
|
|
13
|
+
observer.disconnect(); // 不再观察
|
|
14
|
+
}).observe({ entryTypes: ['largest-contentful-paint'] }); // 观察页面中最大的元素
|
|
15
|
+
new PerformanceObserver((entryList, observer) => {
|
|
16
|
+
const firstInput = entryList.getEntries();
|
|
17
|
+
console.log('FID', firstInput);
|
|
18
|
+
if (firstInput) {
|
|
19
|
+
let inputDelay = firstInput.processingStart - firstInput.startTime;
|
|
20
|
+
const duration = firstInput.duration;
|
|
21
|
+
if (inputDelay > 0 || duration > 0) {
|
|
22
|
+
tracker.send({
|
|
23
|
+
kind: 'experience',
|
|
24
|
+
type: 'firstInputDelay',
|
|
25
|
+
inputDelay,
|
|
26
|
+
duration,
|
|
27
|
+
startTime: firstInput.startTime
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
observer.disconnect(); // 不再观察
|
|
32
|
+
}).observe({ type: 'first-input', buffered: true }); // 观察页面中最大的元素
|
|
33
|
+
onload(function () {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
console.dir(window.performance);
|
|
36
|
+
const { fetchStart, connectStart, connectEnd, requestStart, responseStart, responseEnd, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, loadEventStart,
|
|
37
|
+
// loadEventEnd
|
|
38
|
+
} = performance.getEntriesByType('navigation')[0];
|
|
39
|
+
tracker.send({
|
|
40
|
+
kind: 'experience',
|
|
41
|
+
type: 'timing',
|
|
42
|
+
connectTime: connectEnd - connectStart,
|
|
43
|
+
ttfbTime: responseStart - requestStart,
|
|
44
|
+
responseTime: responseEnd - responseStart,
|
|
45
|
+
domContentLoadedTime: domContentLoadedEventEnd - domContentLoadedEventStart,
|
|
46
|
+
timeToInteractive: domInteractive - fetchStart,
|
|
47
|
+
loadTime: loadEventStart - fetchStart // 完整的页面加载时间
|
|
48
|
+
});
|
|
49
|
+
let FP = performance.getEntriesByName('first-paint')[0];
|
|
50
|
+
let FCP = performance.getEntriesByName('first-contentful-paint')[0];
|
|
51
|
+
console.log('FP', FP);
|
|
52
|
+
console.log('FCP', FCP);
|
|
53
|
+
console.log('FMP', FMP);
|
|
54
|
+
console.log('LCP', LCP);
|
|
55
|
+
tracker.send({
|
|
56
|
+
kind: 'experience',
|
|
57
|
+
type: 'paint',
|
|
58
|
+
FP: FP.startTime,
|
|
59
|
+
FCP: FCP.startTime,
|
|
60
|
+
FMP: FMP.startTime,
|
|
61
|
+
LCP: LCP.startTime,
|
|
62
|
+
});
|
|
63
|
+
}, 3000);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function injectXHR(data?: any): void;
|
|
1
|
+
export default function injectXHR(data?: any): void;
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import tracker from "../utils/tracker";
|
|
2
|
-
export default function injectXHR(data = {}) {
|
|
3
|
-
let XMLHttpRequest = window.XMLHttpRequest;
|
|
4
|
-
let oldOpen = XMLHttpRequest.prototype.open;
|
|
5
|
-
XMLHttpRequest.prototype.open = function (method, url, async) {
|
|
6
|
-
this.logData = { method, url, async };
|
|
7
|
-
return oldOpen.apply(this, arguments);
|
|
8
|
-
};
|
|
9
|
-
let oldSend = XMLHttpRequest.prototype.send;
|
|
10
|
-
XMLHttpRequest.prototype.send = function (body) {
|
|
11
|
-
if (this.logData) {
|
|
12
|
-
const startTime = Date.now();
|
|
13
|
-
const handler = (type) => (event) => {
|
|
14
|
-
if (this.logData.url.indexOf('app/collect/original/info/report/v2') > -1)
|
|
15
|
-
return;
|
|
16
|
-
if (type !== 'error')
|
|
17
|
-
return;
|
|
18
|
-
let duration = Date.now() - startTime;
|
|
19
|
-
let status = this.status;
|
|
20
|
-
let statusText = this.statusText;
|
|
21
|
-
tracker.send({
|
|
22
|
-
kind: 'stability',
|
|
23
|
-
type: 'xhr',
|
|
24
|
-
eventType: event.type,
|
|
25
|
-
pathname: this.logData.url,
|
|
26
|
-
status: status + '-' + statusText,
|
|
27
|
-
duration,
|
|
28
|
-
response: this.response ? JSON.stringify(this.response) : '',
|
|
29
|
-
params: body || '',
|
|
30
|
-
title: 'xhr',
|
|
31
|
-
reason: status + '-' + statusText + ` ${this.logData.url} ${this.response ? JSON.stringify(this.response) : ''}`,
|
|
32
|
-
...data
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
this.addEventListener('load', handler('load'), false);
|
|
36
|
-
this.addEventListener('error', handler('error'), false);
|
|
37
|
-
this.addEventListener('abort', handler('abort'), false);
|
|
38
|
-
}
|
|
39
|
-
return oldSend.apply(this, arguments);
|
|
40
|
-
};
|
|
41
|
-
}
|
|
1
|
+
import tracker from "../utils/tracker";
|
|
2
|
+
export default function injectXHR(data = {}) {
|
|
3
|
+
let XMLHttpRequest = window.XMLHttpRequest;
|
|
4
|
+
let oldOpen = XMLHttpRequest.prototype.open;
|
|
5
|
+
XMLHttpRequest.prototype.open = function (method, url, async) {
|
|
6
|
+
this.logData = { method, url, async };
|
|
7
|
+
return oldOpen.apply(this, arguments);
|
|
8
|
+
};
|
|
9
|
+
let oldSend = XMLHttpRequest.prototype.send;
|
|
10
|
+
XMLHttpRequest.prototype.send = function (body) {
|
|
11
|
+
if (this.logData) {
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const handler = (type) => (event) => {
|
|
14
|
+
if (this.logData.url.indexOf('app/collect/original/info/report/v2') > -1)
|
|
15
|
+
return;
|
|
16
|
+
if (type !== 'error')
|
|
17
|
+
return;
|
|
18
|
+
let duration = Date.now() - startTime;
|
|
19
|
+
let status = this.status;
|
|
20
|
+
let statusText = this.statusText;
|
|
21
|
+
tracker.send({
|
|
22
|
+
kind: 'stability',
|
|
23
|
+
type: 'xhr',
|
|
24
|
+
eventType: event.type,
|
|
25
|
+
pathname: this.logData.url,
|
|
26
|
+
status: status + '-' + statusText,
|
|
27
|
+
duration,
|
|
28
|
+
response: this.response ? JSON.stringify(this.response) : '',
|
|
29
|
+
params: body || '',
|
|
30
|
+
title: 'xhr',
|
|
31
|
+
reason: status + '-' + statusText + ` ${this.logData.url} ${this.response ? JSON.stringify(this.response) : ''}`,
|
|
32
|
+
...data
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
this.addEventListener('load', handler('load'), false);
|
|
36
|
+
this.addEventListener('error', handler('error'), false);
|
|
37
|
+
this.addEventListener('abort', handler('abort'), false);
|
|
38
|
+
}
|
|
39
|
+
return oldSend.apply(this, arguments);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function onload(cb: any): void;
|
|
1
|
+
export default function onload(cb: any): void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export default function onload(cb) {
|
|
2
|
-
if (document.readyState) {
|
|
3
|
-
cb();
|
|
4
|
-
}
|
|
5
|
-
else {
|
|
6
|
-
window.addEventListener('load', cb);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
1
|
+
export default function onload(cb) {
|
|
2
|
+
if (document.readyState) {
|
|
3
|
+
cb();
|
|
4
|
+
}
|
|
5
|
+
else {
|
|
6
|
+
window.addEventListener('load', cb);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
declare class SendTracker {
|
|
2
|
-
url: string;
|
|
3
|
-
constructor();
|
|
4
|
-
send(data?: any): void;
|
|
5
|
-
}
|
|
6
|
-
declare const _default: SendTracker;
|
|
7
|
-
export default _default;
|
|
1
|
+
declare class SendTracker {
|
|
2
|
+
url: string;
|
|
3
|
+
constructor();
|
|
4
|
+
send(data?: any): void;
|
|
5
|
+
}
|
|
6
|
+
declare const _default: SendTracker;
|
|
7
|
+
export default _default;
|