spy-client 2.0.7 → 2.1.1

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 (41) hide show
  1. package/README.md +119 -10
  2. package/dist/head/base.d.ts +1 -1
  3. package/dist/lib/huffman.d.ts +9 -0
  4. package/dist/lib/interface.d.ts +59 -1
  5. package/dist/lib/util.d.ts +22 -0
  6. package/dist/module/longtask.d.ts +1 -1
  7. package/dist/module/resource.d.ts +19 -9
  8. package/dist/module/tti.d.ts +1 -1
  9. package/dist/spy-client-basic.esm.js +233 -1167
  10. package/dist/spy-client-basic.iife.js +237 -1171
  11. package/dist/spy-client-basic.iife.min.js +1 -1
  12. package/dist/spy-client-basic.js +238 -1172
  13. package/dist/spy-client-basic.min.js +1 -1
  14. package/dist/spy-client-basic.mjs +82 -54
  15. package/dist/spy-client.d.ts +5 -4
  16. package/dist/spy-client.esm.js +1393 -5662
  17. package/dist/spy-client.iife.js +1401 -5670
  18. package/dist/spy-client.iife.min.js +1 -1
  19. package/dist/spy-client.js +1402 -5671
  20. package/dist/spy-client.min.js +1 -1
  21. package/dist/spy-client.mjs +704 -455
  22. package/dist/spy-head.js +330 -276
  23. package/dist/spy-head.min.js +1 -1
  24. package/dist/spy-local-cache.d.ts +18 -0
  25. package/dist/spy-local-cache.js +690 -0
  26. package/dist/spy-local-cache.min.js +1 -0
  27. package/example/index.html +8 -2
  28. package/example/local-cache.html +97 -0
  29. package/example/saveCache.js +41 -0
  30. package/karma.conf.js +111 -0
  31. package/package.json +21 -20
  32. package/src/head/error.ts +14 -15
  33. package/src/head/whitescreen.ts +8 -5
  34. package/src/lib/huffman.ts +326 -0
  35. package/src/lib/interface.ts +70 -1
  36. package/src/lib/util.ts +101 -0
  37. package/src/module/resource.ts +226 -129
  38. package/src/spy-client-basic.ts +8 -7
  39. package/src/spy-client.ts +15 -6
  40. package/src/spy-local-cache.ts +385 -0
  41. package/src/types/globals.d.ts +1 -1
@@ -0,0 +1 @@
1
+ !function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).SpyLocalCache=o()}(this,function(){"use strict";var n=function(t,o){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var r in o)o.hasOwnProperty(r)&&(t[r]=o[r])})(t,o)};function t(t,o){function r(){this.constructor=t}n(t,o),t.prototype=null===o?Object.create(o):(r.prototype=o.prototype,new r)}var c=(o.prototype.preOrder=function(t){t.push(this),this.left&&this.left.preOrder(t),this.right&&this.right.preOrder(t)},o);function o(t,o){this.data=t,this.weight=o}function r(t){if(null==t)return null;var e={};return function t(o,r,n){n=[].concat(n);n.push(r),null!=o&&(null==o.data?(t(o.left,"0",n),t(o.right,"1",n)):e[o.data]=n.join(""))}(t,"",[]),e}function e(t){var o=r(function(t){for(var o=function(t,o){return t.weight-o.weight};1<t.length;){t.sort(o);var r,n=t.shift(),e=t.shift();n&&e&&((r=new c(null,n.weight+e.weight)).left=n,r.right=e,t.unshift(r))}return t.shift()}(function(t){for(var o=[],r={},n=0,e=t;n<e.length;n++){var i=e[n];null==r[i]?r[i]=1:r[i]++}for(var s=0,a=Object.entries(r);s<a.length;s++){var h=a[s],u=h[0],h=h[1];o.push(new c(u,h))}return o}(t)));return{result:function(t){for(var o=t.join(""),t=Math.ceil(o.length/8),r=new Array(t+1),n=0,e="",i=0;i<o.length;i+=8)e=o.substring(i,i+8),r[n]=parseInt(e,2),n++;return r[n]=e.length,r}(function(t,o){for(var r=[],n=0,e=t;n<e.length;n++){var i=e[n];r.push(o[i])}return r}(t,o)),codes:o}}function i(t,o){for(var r,n,e=[],i=0;i<o.length-1;i++){var s=i!==o.length-2;e.push((r=s,n=o[i],r&&(n|=256),n=Number(n).toString(2),r?n.substring(n.length-8):n))}var a=e[e.length-1],h=o[o.length-1],a="00000000".substring(8-(h-a.length))+a;e[e.length-1]=a;for(var u={},c=0,p=Object.entries(t);c<p.length;c++){var l=p[c],f=l[0];u[l[1]]=f}for(var g=e.join(""),d=[],y=g.length,i=0;i<y;){for(var v=1,s=!0,m=null;s&&i+v<=y;){if(""===(f=g.substring(i,i+v)))break;(m=u[f])?s=!1:v++}d.push(parseInt(m)),i+=v}return d}function s(t){for(var o=[],r=0;r<t.length;r++)o.push(t.charCodeAt(r));return o}function a(t){for(var o="",r=0,n=t;r<n.length;r++){var e=n[r];o+=String.fromCharCode(e)}return o}var h=(u.prototype.set=function(t,o){},u.prototype.get=function(t,o){},u.prototype.rm=function(t){},u);function u(){}var p,l=(t(f,p=h),f.isSupport=function(){return!!window.localStorage},f.prototype.set=function(t,o){try{localStorage.setItem(t,o)}catch(t){console.error(t)}},f.prototype.get=function(t,o){var r=null;try{r=localStorage.getItem(t)}catch(t){console.error(t)}o&&o(r)},f.prototype.rm=function(t){try{localStorage.removeItem(t)}catch(t){console.error(t)}},f);function f(){return null!==p&&p.apply(this,arguments)||this}var g,d=(t(y,g=h),y.isSupport=function(){return!!window.indexedDB},y.prototype.set=function(t,o){},y.prototype.get=function(t,o){},y);function y(){return null!==g&&g.apply(this,arguments)||this}function v(t,o){if(!t)return"";(o=void 0===o?!1:o)||(t=function(t){for(var o="",r=0;r<t.length;r++){var n=t.charCodeAt(r);n<128?o+=String.fromCharCode(n):(127<n&&n<2048?o+=String.fromCharCode(n>>6|192):(o+=String.fromCharCode(n>>12|224),o+=String.fromCharCode(n>>6&63|128)),o+=String.fromCharCode(63&n|128))}return o}(t));function r(){a.push(1<h.length?String.fromCharCode(s[h]):h)}var n,e,i,s={},a=[],h=t.charAt(0),u=h,c=u,p=256;for(o&&a.push(h),n=1;n<t.length;n++)e=t.charAt(n),o?(i=t.charCodeAt(n),h=i<256?e:s[i]||h+u,a.push(h),u=h.charAt(0),s[p++]=c+u,c=h):s.hasOwnProperty(h+e)?h+=e:(r(),s[h+e]=p++,h=e);o||r();var l=a.join("");return l=o?function(t){for(var o,r,n="",e=0,i=0;e<t.length;)(o=t.charCodeAt(e))<128?(n+=String.fromCharCode(o),e++):191<o&&o<224?(i=t.charCodeAt(e+1),n+=String.fromCharCode((31&o)<<6|63&i),e+=2):(i=t.charCodeAt(e+1),r=t.charCodeAt(e+2),n+=String.fromCharCode((15&o)<<12|(63&i)<<6|63&r),e+=3);return n}(l):l}function m(t){void 0===t&&(t={}),this.tmpList=[],this.option=function(){for(var t=[],o=0;o<arguments.length;o++)t[o]=arguments[o];return(Object.assign||function(t){for(var o,r=1,n=arguments.length;r<n;r++)for(var e in o=arguments[r])Object.prototype.hasOwnProperty.call(o,e)&&(t[e]=o[e]);return t}).apply(this,t)}({defaultTrigger:!0,compress:"lzw",key:"SpyLocalCache",interval:500,onFlush:function(){},storage:d.isSupport()?"indexedDB":l.isSupport()?"localstorage":"empty"},t),this.load=this.load.bind(this),this.init()}return m.prototype.init=function(){"indexedDB"===this.option.storage?this.storage=new d:"localstorage"===this.option.storage?this.storage=new l:this.storage=new h,"complete"===document.readyState?this.load():window.addEventListener("load",this.load)},m.prototype.load=function(){-1<location.search.indexOf("_FlushLogLocalCache=1")&&this.option.defaultTrigger&&this.flushLog()},m.prototype.addLog=function(t){var o=this;t=JSON.stringify(t),this.tmpList.push(t),this.timer&&clearTimeout(this.timer),this.timer=setTimeout(function(){o.save()},this.option.interval)},m.prototype.getData=function(n){var e=this;try{this.storage.get(this.option.key,function(r){r?e.storage.get(e.option.key+"Codes",function(t){var o=[];try{t=t&&JSON.parse(t);o=e.unzip(r,t).split("\n")}catch(t){console.error(t)}n(o)}):n([])})}catch(t){console.error(t),n([])}},m.prototype.save=function(){var r=this;this.getData(function(t){var o=(29<t.length?t.slice(t.length-29,t.length):t).concat(r.tmpList).join("\n"),t=r.zip(o);t.codes?(o=JSON.stringify(t.codes),r.storage.set(r.option.key+"Codes",o)):r.storage.rm(r.option.key+"Codes"),r.storage.set(r.option.key,t.result),r.tmpList=[]})},m.prototype.flushLog=function(){var r=this;this.getData(function(o){try{for(var t=0;t<o.length;t++)o[t]=JSON.parse(o[t])}catch(t){o=[],r.storage.rm(r.option.key),console.error(t)}for(t=0;t<r.tmpList.length;t++)o.push(JSON.parse(r.tmpList[t]));r.option.onFlush&&r.option.onFlush(o)})},m.prototype.zip=function(t){return"lzw"===this.option.compress?{codes:null,result:v(t)}:"huffman"===this.option.compress?(o=(r=e(s(o=t))).result,{codes:r.codes,result:a(o)}):{codes:null,result:t};var o,r},m.prototype.unzip=function(t,o){return"lzw"===this.option.compress?v(t,!0):"huffman"===this.option.compress?a(i(o,s(t))):t},m});
@@ -51,7 +51,7 @@
51
51
  TypeScriptJavaScriptJavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页。可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误强类型,支持静态和动态类型弱类型,没有静态类型选项最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用支持模块、泛型和接口不支持模块,泛型或接口支持 ES3,ES4,ES5 和 ES6 等不支持编译其他 ES3,ES4,ES5 或 ES6 功能社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持
52
52
  </p>
53
53
  <img src="https://t7.baidu.com/it/u=1211001202,1148572269&fm=193&app=53&size=w414&n=0&g=0n&f=jpeg?sec=1594890084&t=cde9e5bcd0b06de0c989741a7853bd06&a=1" alt="">
54
- <img src="https://expertimg.cdn.bcebos.com/expertcms/med/zhongyao.jpg" alt="">
54
+ <img class="bigimg" src="https://expertimg.cdn.bcebos.com/expertcms/med/zhongyao.jpg" alt="">
55
55
  <script>window.perfFirstScreen = performance.now();</script>
56
56
  </div>
57
57
  <script src="https://mss0.bdstatic.com/se/static/js/iphone/zbios/zbiosT_f69.js"></script>
@@ -240,7 +240,8 @@ spy.listenTTI(function (metric) {
240
240
 
241
241
 
242
242
  // 数据类型:性能,触发时间:500MsAfterOnLoad
243
- spy.listenResource(function (metric) {
243
+ spy.listenResource(function (metric, hostMetric) {
244
+ console.log('hostMetric', hostMetric);
244
245
  spy.sendPerf({
245
246
  info: metric
246
247
  });
@@ -256,6 +257,11 @@ spy.listenHttpResource(function (info) {
256
257
  console.log('info', info);
257
258
  });
258
259
 
260
+ // 数据类型:异常,触发时间:500MsAfterOnLoad
261
+ spy.listenSlowResource(function (info) {
262
+ console.log('slow info', info);
263
+ }, {threshold: 20});
264
+
259
265
  // 数据类型:性能,触发时间:OnLoad
260
266
  spy.listenFSPLongTask(function (metric) {
261
267
  spy.sendPerf({
@@ -0,0 +1,97 @@
1
+ <html lang="en">
2
+ <head>
3
+ <meta charset="UTF-8">
4
+ <title>SPY Client Test</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <script src="/dist/spy-head.js"></script>
8
+ <script>
9
+ // 配置
10
+ window.__spyHead && window.__spyHead.init({
11
+ pid: '1_1000',
12
+ lid: '',
13
+ // 数据类型:异常,触发时间:OnLoadResourceError
14
+ resourceError: {
15
+ group: 'resource',
16
+ sample: 1,
17
+ handler: function (data) {
18
+
19
+ }
20
+ },
21
+ // 数据类型:异常,触发时间:OnJSError
22
+ jsError: {
23
+ group: 'js',
24
+ sample: 1,
25
+ handler: function (data) {
26
+
27
+ }
28
+ },
29
+ // 数据类型:异常,触发时间:OnJudgeReturnFalseWhenTimeout
30
+ whiteScreenError: {
31
+ sample: 1,
32
+ group: 'whiteScreen',
33
+ selector: 'body',
34
+ subSelector: 'button1',
35
+ timeout: 2000,
36
+ handler: function (data) {
37
+
38
+ }
39
+ }
40
+ });
41
+
42
+
43
+ function en(c){
44
+ var x='charCodeAt',
45
+ b, e={},
46
+ f=c.split(""),d=[],a=f[0],g=256;for(b=1;b<f.length;b++)c=f[b],null!=e[a+c]?a+=c:(d.push(1<a.length?e[a]:a[x](0)),e[a+c]=g,g++,a=c);d.push(1<a.length?e[a]:a[x](0));for(b=0;b<d.length;b++)d[b]=String.fromCharCode(d[b]);return d.join("")}
47
+
48
+ function de(b){var a,e={},d=b.split(""),c=f=d[0],g=[c],h=o=256;for(b=1;b<d.length;b++)a=d[b].charCodeAt(0),a=h>a?d[b]:e[a]?e[a]:f+c,g.push(a),c=a.charAt(0),e[o]=f+c,o++,f=a;return g.join("")}
49
+
50
+ </script>
51
+ </head>
52
+ <body>
53
+ <!-- <div style="height: 667px;"> -->
54
+ <div id="main">
55
+ <div>open</div>
56
+
57
+ <p>
58
+ TypeScriptJavaScriptJavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页。可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误强类型,支持静态和动态类型弱类型,没有静态类型选项最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用支持模块、泛型和接口不支持模块,泛型或接口支持 ES3,ES4,ES5 和 ES6 等不支持编译其他 ES3,ES4,ES5 或 ES6 功能社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持
59
+ </p>
60
+
61
+ </div>
62
+ <script src="https://mss0.bdstatic.com/se/static/js/iphone/zbios/zbiosT_f69.js"></script>
63
+ <script src="/dist/spy-local-cache.js"></script>
64
+
65
+ <script type="text/javascript">
66
+ const localCache = new SpyLocalCache({
67
+ storage: 'localstorage',
68
+ // compress: 'huffman',
69
+ // compress: 'no',
70
+ compress: 'lzw',
71
+ onFlush(list) {
72
+ console.log('flushed list', list);
73
+ },
74
+ });
75
+
76
+ // 当有22条如下日志时
77
+ // lzw 压缩率 68%,耗时 2ms
78
+ // huffman压缩率 21% ,耗时2ms
79
+ localCache.addLog({
80
+ type: 'perf',
81
+ info: {
82
+ res: 200,
83
+ },
84
+ });
85
+
86
+ localCache.addLog({
87
+ type: 3,
88
+ fm: 'disp',
89
+ data: [{"base":{"size":{"doc":{"w":360,"h":4875},"wind":{"w":360,"h":640},"scr":{"w":360,"h":640}},"vsb":"visible","num":16},"t":1629773746698,"path":"/s"}],
90
+ qid: 10991431029479106376,
91
+ did: '8dd09c47c7bc90c9fd7274f0ad2c581e',
92
+ q: '刘德华',
93
+ t: 1629773746698
94
+ });
95
+ </script>
96
+ </body>
97
+ </html>
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @file saveCache.js
3
+ * @author chaiyanchen(chaiyanchen@baidu.com)
4
+ * 起一个简单的本地服务,可用于接收spy-local-cache中缓存的数据
5
+ */
6
+
7
+ const fs = require('fs');
8
+
9
+ const fastify = require('fastify')({
10
+ logger: true,
11
+ });
12
+
13
+ fastify.register(require('fastify-cors'), {});
14
+
15
+ // 声明路由
16
+ fastify.post('/saveData', function (request, reply) {
17
+ try {
18
+ const jsonData = JSON.stringify(request.body);
19
+ const filePath = `jsonData_${new Date().getTime()}.json`;
20
+ fs.writeFile(filePath, jsonData, 'utf8', err => {
21
+ if (err) {
22
+ console.error(err);
23
+ return;
24
+ }
25
+ console.log('写入成功!');
26
+ });
27
+ }
28
+ catch (error) {
29
+ console.log('写入失败:', error);
30
+ }
31
+
32
+ reply.send({hello: 'world'});
33
+ });
34
+
35
+ fastify.listen(3000, function (err, address) {
36
+ if (err) {
37
+ fastify.log.error(err);
38
+ process.exit(1);
39
+ }
40
+ fastify.log.info(`server listening on ${address}`);
41
+ });
package/karma.conf.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @file karma测试配置,放弃了karma-typescript,不支持相对导入,采用了webpack
3
+ * @author kaivean
4
+ */
5
+
6
+
7
+ // const webpack = require('webpack');
8
+
9
+ module.exports = config => {
10
+ config.set({
11
+
12
+ // base path that will be used to resolve all patterns (eg. files, exclude)
13
+ basePath: './',
14
+
15
+ // frameworks to use
16
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
17
+ frameworks: ['jasmine', 'karma-typescript'],
18
+
19
+ // plugins: ['karma-webpack'],
20
+ client: {
21
+ jasmine: {
22
+ random: false,
23
+ },
24
+ },
25
+
26
+ // list of files / patterns to load in the browser
27
+ files: [
28
+ 'dist/spy-head.js', // 先加载
29
+ // 'dist/spy-client.js', // 先加载
30
+ // 'src/index.ts',
31
+ // 'test/**/basicSpec.ts',
32
+ // 'test/**/headSpec.ts',
33
+ // 'test/**/metricSpec.ts',
34
+ // 'test/**/*Spec.ts',
35
+ {
36
+ pattern: 'test/**/*Spec.ts',
37
+ watched: false, // 监听变化
38
+ included: true, // script加载到页面里
39
+ served: true, // be served by Karma's webserver
40
+ nocache: false, // 为了保证测试到一些case,比如lcp等
41
+ },
42
+ ],
43
+
44
+ // list of files / patterns to exclude
45
+ exclude: [
46
+
47
+ ],
48
+
49
+ // preprocess matching files before serving them to the browser
50
+ // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
51
+ preprocessors: {
52
+ 'test/**/*.ts': ['karma-typescript'],
53
+ },
54
+
55
+ karmaTypescriptConfig: {
56
+ exclude: ['node_modules'],
57
+ include: ['test/**/*.ts'],
58
+ compilerOptions: {
59
+ baseUrl: '.',
60
+ paths: {
61
+ 'spy-client': ['dist/spy-client.js'],
62
+ },
63
+ },
64
+ transformPath(filepath) {
65
+ return filepath.replace(/\.(ts|tsx)$/, '.js');
66
+ },
67
+ // tsconfig: './tsconfig.json',
68
+ },
69
+
70
+ reporters: ['progress', 'kjhtml', 'karma-typescript'],
71
+
72
+ // web server port
73
+ port: 9876,
74
+
75
+ // enable / disable colors in the output (reporters and logs)
76
+ colors: true,
77
+
78
+ // level of logging
79
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
80
+ logLevel: config.LOG_INFO,
81
+
82
+ // enable / disable watching file and executing tests whenever any file changes
83
+ autoWatch: true,
84
+
85
+ // start these browsers
86
+ // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
87
+ browsers: ['Chrome'],
88
+
89
+ // you can define custom flags
90
+ customLaunchers: {
91
+ ChromeHeadlessNoSandbox: {
92
+ base: 'ChromeHeadless',
93
+ flags: ['--no-sandbox'],
94
+ },
95
+ },
96
+
97
+ // Continuous Integration mode
98
+ // if true, Karma captures browsers, runs the tests and exits
99
+ singleRun: true,
100
+
101
+ // Concurrency level
102
+ // how many browser should be started simultaneous
103
+ concurrency: Infinity,
104
+ });
105
+
106
+ if (process.env.TRAVIS) {
107
+ config.set({
108
+ browsers: ['ChromeHeadless', 'ChromeHeadlessNoSandbox'],
109
+ });
110
+ }
111
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spy-client",
3
- "version": "2.0.7",
3
+ "version": "2.1.1",
4
4
  "description": "spy client",
5
5
  "main": "dist/spy-client.js",
6
6
  "module": "dist/spy-client.esm.js",
@@ -14,7 +14,7 @@
14
14
  "build": "rollup -c --environment NODE_ENV:production",
15
15
  "lint": "eslint src/**/*.ts",
16
16
  "example": "npm run dev && echo 'open url http://localhost:8000/example' && python -m SimpleHTTPServer 8000 ",
17
- "test": "karma start karma.conf.ts",
17
+ "test": "karma start karma.conf.js",
18
18
  "release_pre": "npm version patch",
19
19
  "release": "rm -fr dist && npm run build && npm run lint && npm run test && npm publish",
20
20
  "release_post": "git push origin master && git push origin --tags"
@@ -27,52 +27,53 @@
27
27
  "core-js": "^3.6.4"
28
28
  },
29
29
  "devDependencies": {
30
- "@babel/core": "^7.5.5",
30
+ "@babel/core": "^7.15.0",
31
+ "@babel/eslint-parser": "^7.15.0",
32
+ "@babel/eslint-plugin": "^7.14.5",
31
33
  "@babel/preset-env": "^7.5.5",
32
- "@ecomfe/eslint-config": "^3.2.0",
34
+ "@ecomfe/eslint-config": "^7.2.1",
33
35
  "@rollup/plugin-commonjs": "^11.0.2",
34
36
  "@rollup/plugin-node-resolve": "^7.1.1",
35
- "@rollup/plugin-typescript": "^4.0.0",
37
+ "@rollup/plugin-typescript": "^8.2.5",
36
38
  "@types/glob": "^7.1.1",
37
39
  "@types/jasmine": "^3.5.10",
38
40
  "@types/node": "^12.6.8",
39
41
  "@types/uglifyjs-webpack-plugin": "^1.1.0",
40
42
  "@types/webpack": "^4.4.35",
41
43
  "@types/webpack-merge": "^4.1.5",
42
- "@typescript-eslint/eslint-plugin": "^2.25.0",
43
- "@typescript-eslint/parser": "^2.25.0",
44
+ "@typescript-eslint/eslint-plugin": "^4.29.2",
45
+ "@typescript-eslint/parser": "^4.29.2",
44
46
  "babel-eslint": "^10.1.0",
45
47
  "babel-loader": "^8.0.6",
46
48
  "cache-loader": "^4.1.0",
47
49
  "css-loader": "^3.1.0",
48
50
  "eslint": "^6.8.0",
49
51
  "eslint-plugin-babel": "^5.3.0",
50
- "eslint-plugin-import": "^2.20.1",
52
+ "eslint-plugin-import": "^2.24.1",
53
+ "fastify": "^3.21.0",
54
+ "fastify-cors": "^6.0.2",
51
55
  "fecs": "^1.6.4",
52
56
  "file-loader": "^4.1.0",
53
57
  "jasmine-core": "^3.4.0",
54
- "karma": "^4.3.0",
58
+ "karma": "^6.3.4",
55
59
  "karma-chrome-launcher": "^3.1.0",
56
60
  "karma-jasmine": "^2.0.1",
57
61
  "karma-jasmine-html-reporter": "^1.4.2",
58
- "karma-webpack": "^4.0.2",
62
+ "karma-typescript": "^5.5.2",
59
63
  "less": "^3.9.0",
60
64
  "less-loader": "^5.0.0",
61
- "rollup": "^2.2.0",
65
+ "rollup": "^2.56.2",
62
66
  "rollup-plugin-babel": "^4.4.0",
63
67
  "rollup-plugin-replace": "^2.2.0",
64
- "rollup-plugin-typescript2": "^0.26.0",
68
+ "rollup-plugin-typescript2": "^0.30.0",
65
69
  "rollup-plugin-uglify": "^6.0.4",
66
70
  "stylus": "^0.54.5",
67
71
  "stylus-loader": "^3.0.2",
68
72
  "ts-loader": "^6.0.4",
69
73
  "ts-node": "^8.3.0",
70
- "typescript": "^3.6.2",
74
+ "typescript": "^4.3.5",
71
75
  "uglifyjs-webpack-plugin": "^2.1.3",
72
- "url-loader": "^2.1.0",
73
- "webpack": "^4.36.1",
74
- "webpack-cli": "^3.3.6",
75
- "webpack-merge": "^4.2.1"
76
+ "url-loader": "^2.1.0"
76
77
  },
77
78
  "keywords": [
78
79
  "spy",
@@ -120,8 +121,8 @@
120
121
  "browserslist": [
121
122
  "> 1%",
122
123
  "last 2 versions",
123
- "ie >= 8",
124
- "android >= 2.3",
125
- "ios >= 7"
124
+ "ie >= 9",
125
+ "android >= 4",
126
+ "ios >= 9"
126
127
  ]
127
128
  }
package/src/head/error.ts CHANGED
@@ -8,6 +8,8 @@ import {
8
8
  SpyHeadConf,
9
9
  ErrorConf,
10
10
  } from '../lib/spyHeadInterface';
11
+ import {getUrlInfo, getxpath} from '../lib/util';
12
+
11
13
  import spyHead from './base';
12
14
 
13
15
  export function init(conf: SpyHeadConf) {
@@ -17,20 +19,7 @@ export function init(conf: SpyHeadConf) {
17
19
  const isSendResource = Math.random() < (resourceError.sample ? resourceError.sample : 0);
18
20
 
19
21
  const winerrors = spyHead.winerrors;
20
-
21
- function getxpath(el: HTMLElement) {
22
- const xpath = [];
23
- while (el && el.nodeType === 1 && el !== el.parentNode) {
24
- xpath.push(el.tagName.toLowerCase());
25
- if (el === document.body) {
26
- break;
27
- }
28
- el = el.parentNode as HTMLElement; // 修复缺陷检查
29
- }
30
- return {
31
- xpath: xpath.join('<'),
32
- };
33
- }
22
+ let resourceErrorCount = 0;
34
23
 
35
24
  function spyListenError(event: Event) {
36
25
  try {
@@ -47,6 +36,7 @@ export function init(conf: SpyHeadConf) {
47
36
  info.deviceMemory = navigator.deviceMemory || 0;
48
37
  info.hardwareConcurrency = navigator.hardwareConcurrency || 0;
49
38
 
39
+ // JS错误
50
40
  if (srcElement === window) {
51
41
  obj.group = jsError.group;
52
42
 
@@ -72,7 +62,6 @@ export function init(conf: SpyHeadConf) {
72
62
  const item = spyHead.winerrors[index];
73
63
  const prefix = item.count > 1 ? `(${item.count})` : '';
74
64
  historys.push(prefix + (item.msg as string));
75
-
76
65
  }
77
66
 
78
67
  info.hisErrors = historys.join('----');
@@ -86,16 +75,24 @@ export function init(conf: SpyHeadConf) {
86
75
  spyHead.send(obj);
87
76
  }
88
77
  }
78
+ // 资源错误
89
79
  else {
90
80
  obj.group = resourceError.group;
91
81
  (obj.dim as any).type = (srcElement as HTMLElement).tagName.toLowerCase();
82
+
92
83
  const url = (srcElement as HTMLScriptElement).src || (srcElement as HTMLLinkElement).href;
93
84
  info.msg = url || 'unknown load eror';
94
85
 
86
+ (obj.dim as any).host = getUrlInfo(url).host;
87
+
95
88
  if (el && (el as HTMLElement).tagName === 'IMG') {
96
89
  info.xpath = getxpath(el as HTMLElement).xpath;
97
90
  }
98
91
 
92
+ if (resourceErrorCount) {
93
+ info.hisErrCount = resourceErrorCount;
94
+ }
95
+
99
96
  let allow: boolean | undefined | void = true;
100
97
  if (resourceError.handler) {
101
98
  allow = resourceError.handler(obj);
@@ -104,6 +101,8 @@ export function init(conf: SpyHeadConf) {
104
101
  if (allow !== false && isSendResource) {
105
102
  spyHead.send(obj);
106
103
  }
104
+
105
+ resourceErrorCount++;
107
106
  }
108
107
 
109
108
  // 有些错误一下出现很多次,都聚合都一个错误,加上次数