jason-trace-log 1.0.11 → 1.0.13

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 CHANGED
@@ -1,224 +1,17 @@
1
1
 
2
+ # 项目介绍
2
3
 
3
- ## 核心原因
4
+ 数据上报SDK,用于上报数据到华为云LTS。
4
5
 
5
- 根据 **HTML 规范和浏览器实现**,资源加载错误(如 `<img>`、`<script>`、`<link>` 等元素的加载失败)的 `error` 事件是 **非冒泡事件(non-bubbling event)**。
6
+ # 项目结构
6
7
 
7
- ## 1. HTML 规范定义
8
-
9
- ### 资源加载错误的特性
10
-
11
- - **事件类型**:`error` 事件
12
- - **冒泡行为**:**不支持冒泡**(non-bubbling)
13
- - **可取消性**:不可取消(non-cancelable)
14
- - **触发位置**:仅在触发错误的元素本身
15
-
16
- ### JavaScript 运行时错误的特性
17
-
18
- - **事件类型**:`error` 事件
19
- - **冒泡行为**:**支持冒泡**(bubbling)
20
- - **可取消性**:不可取消(non-cancelable)
21
- - **触发位置**:在 `window` 对象上
22
-
23
- ## 2. 事件传播机制对比
24
-
25
- ### 资源加载错误(不冒泡)
26
-
27
- ```
28
- 事件传播流程:
29
- ┌─────────────────────────────────────┐
30
- │ window (捕获阶段) ← 可以在这里捕获 │
31
- │ ↓ │
32
- │ document (捕获阶段) │
33
- │ ↓ │
34
- │ <img> (目标阶段) ← 事件在这里触发 │
35
- │ ✗ 停止,不继续冒泡 │
36
- └─────────────────────────────────────┘
37
- ```
38
-
39
- ### JavaScript 运行时错误(会冒泡)
40
-
41
- ```
42
- 事件传播流程:
43
- ┌─────────────────────────────────────┐
44
- │ window (捕获阶段) │
45
- │ ↓ │
46
- │ document (捕获阶段) │
47
- │ ↓ │
48
- │ <script> (目标阶段) ← 错误在这里发生 │
49
- │ ↓ │
50
- │ document (冒泡阶段) │
51
- │ ↓ │
52
- │ window (冒泡阶段) ← 可以在这里捕获 │
53
- └─────────────────────────────────────┘
54
- ```
55
-
56
- ## 3. 为什么这样设计?
57
-
58
- ### 3.1 性能考虑
59
-
60
- 资源加载错误非常常见(如广告图片、第三方脚本等),如果每个错误都冒泡到 `window`,会产生大量事件传播,影响性能。
61
-
62
- ```javascript
63
- // 假设页面有 100 个广告图片,其中 10 个加载失败
64
- // 如果都冒泡到 window,会产生 10 次事件传播
65
- // 如果不冒泡,只在元素本身处理,性能更好
66
- ```
67
-
68
- ### 3.2 语义分离
69
-
70
- 资源加载错误和 JavaScript 运行时错误是两种不同的错误类型:
71
-
72
- - **资源加载错误**:网络问题、文件不存在等,属于**资源获取失败**
73
- - **JavaScript 错误**:代码执行问题,属于**程序逻辑错误**
74
-
75
- 将它们分开处理更符合语义。
76
-
77
- ### 3.3 避免误捕获
78
-
79
- 如果资源错误冒泡,可能会被全局错误处理器误判为 JavaScript 错误:
80
-
81
- ```javascript
82
- // 如果资源错误冒泡,这个 handler 会捕获到
83
- window.onerror = function(message, source, lineno, colno, error) {
84
- // 这里会误判:图片加载失败 vs JavaScript 错误
85
- // 无法区分是哪种错误
86
- }
87
8
  ```
88
-
89
- ### 3.4 元素级处理更合适
90
-
91
- 资源加载错误通常需要在元素级别处理(如显示占位图、重试加载等),不需要全局处理:
92
-
93
- ```html
94
- <!-- 元素级处理更合适 -->
95
- <img
96
- src="/image.png"
97
- onerror="this.src='/placeholder.png'"
98
- />
9
+ jason-trace-log/
10
+ ├── src/
11
+ ├── test/
12
+ ├── rollup.config.ts
13
+ ├── tsconfig.json
99
14
  ```
100
15
 
101
- ## 4. 实际验证
102
-
103
- ### 测试代码
104
-
105
- ```html
106
- <!DOCTYPE html>
107
- <html>
108
- <head>
109
- <title>测试资源错误冒泡</title>
110
- </head>
111
- <body>
112
- <!-- 测试图片加载失败 -->
113
- <img src="/non-existent.png" id="test-img" />
114
-
115
- <script>
116
- // 测试 1: 元素级监听(会触发)
117
- document.getElementById('test-img').addEventListener('error', (e) => {
118
- console.log('✅ 元素级 error 事件触发', e.target);
119
- });
120
-
121
- // 测试 2: 冒泡阶段监听 window(不会触发)
122
- window.addEventListener('error', (e) => {
123
- console.log('❌ window 冒泡阶段不会触发', e);
124
- }); // 没有第三个参数,默认是冒泡阶段
125
-
126
- // 测试 3: 捕获阶段监听 window(会触发)
127
- window.addEventListener('error', (e) => {
128
- console.log('✅ window 捕获阶段会触发', e.target);
129
- }, true); // true 表示捕获阶段
130
-
131
- // 测试 4: JavaScript 运行时错误(会冒泡)
132
- setTimeout(() => {
133
- undefined.property; // 这会触发 window error,且会冒泡
134
- }, 1000);
135
- </script>
136
- </body>
137
- </html>
138
- ```
139
-
140
- ### 预期结果
141
-
142
- ```
143
- ✅ 元素级 error 事件触发 <img id="test-img">
144
- ✅ window 捕获阶段会触发 <img id="test-img">
145
- ❌ window 冒泡阶段不会触发(资源错误不冒泡)
146
- ✅ window 冒泡阶段会触发(JavaScript 错误会冒泡)
147
- ```
148
-
149
- ## 5. 如何正确捕获资源加载错误
150
-
151
- ### 方法 1: 使用捕获阶段(推荐)
152
-
153
- ```javascript
154
- // ✅ 正确:使用捕获阶段
155
- window.addEventListener('error', (event) => {
156
- // 判断是否为资源加载错误
157
- if (event.target && (
158
- event.target instanceof HTMLImageElement ||
159
- event.target instanceof HTMLScriptElement ||
160
- event.target instanceof HTMLLinkElement
161
- )) {
162
- console.log('资源加载错误:', event.target.src || event.target.href);
163
- }
164
- }, true); // 关键:第三个参数为 true
165
- ```
166
-
167
- ### 方法 2: 在元素上直接监听
168
-
169
- ```javascript
170
- // ✅ 也可以:在元素上直接监听
171
- const img = document.createElement('img');
172
- img.addEventListener('error', (event) => {
173
- console.log('图片加载失败');
174
- });
175
- img.src = '/non-existent.png';
176
- ```
177
-
178
- ### 方法 3: 使用 MutationObserver(不推荐,复杂)
179
-
180
- ```javascript
181
- // 不推荐:过于复杂
182
- // 监听 DOM 变化,为每个资源元素添加 error 监听器
183
- ```
184
-
185
- ## 6. 代码中的实现
186
-
187
- 在 `baseTrace.ts` 中的正确实现:
188
-
189
- ```typescript
190
- public onGlobalError() {
191
- const _t = this
192
- console.log('onGlobalError')
193
-
194
- // ✅ 使用捕获阶段来捕获资源加载错误
195
- window.addEventListener('error', event => {
196
- console.log('error event: ', event)
197
- _t.saveError(event)
198
- }, true) // true 表示在捕获阶段监听
199
-
200
- // JavaScript 运行时错误也会在捕获阶段被捕获
201
- // 资源加载错误也会在捕获阶段被捕获
202
- }
203
- ```
204
-
205
- ## 7. 总结
206
-
207
- | 错误类型 | 冒泡行为 | 捕获方式 |
208
- |---------|---------|---------|
209
- | **资源加载错误**<br>(img、script、link 等) | ❌ **不冒泡** | ✅ 使用捕获阶段<br>`addEventListener('error', handler, true)` |
210
- | **JavaScript 运行时错误**<br>(TypeError、ReferenceError 等) | ✅ **会冒泡** | ✅ 冒泡或捕获都可以<br>`addEventListener('error', handler)` 或<br>`addEventListener('error', handler, true)` |
211
-
212
- ## 8. 参考资料
213
-
214
- - [MDN: error event](https://developer.mozilla.org/en-US/docs/Web/Events/error)
215
- - [HTML Living Standard: Event handlers](https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers)
216
- - [W3C: Event bubbling and capture](https://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
217
-
218
- ## 9. 关键要点
219
-
220
- 1. **资源加载错误不冒泡**是 HTML 规范的设计,不是 bug
221
- 2. **使用捕获阶段**(`useCapture: true`)可以捕获资源加载错误
222
- 3. **JavaScript 运行时错误会冒泡**,可以在冒泡或捕获阶段捕获
223
- 4. **性能考虑**是设计不冒泡的主要原因之一
224
- 5. **语义分离**让不同类型的错误有更清晰的处理方式
16
+ ## 命令
17
+ 打包 yarn build:js
@@ -853,7 +853,7 @@ var BaseTrace = /** @class */ (function () {
853
853
  console.error('Failed to log trace data:', error);
854
854
  }
855
855
  };
856
- BaseTrace.prototype.info = function (message, tag, extra) {
856
+ BaseTrace.prototype.info = function (message, extra, tag) {
857
857
  this.log({
858
858
  name: 'customer-info',
859
859
  type: TraceDataTypes.LOG,
@@ -865,7 +865,7 @@ var BaseTrace = /** @class */ (function () {
865
865
  extra: extra
866
866
  });
867
867
  };
868
- BaseTrace.prototype.warn = function (message, tag, extra) {
868
+ BaseTrace.prototype.warn = function (message, extra, tag) {
869
869
  this.log({
870
870
  name: 'customer-warning',
871
871
  type: TraceDataTypes.LOG,
@@ -877,7 +877,7 @@ var BaseTrace = /** @class */ (function () {
877
877
  extra: extra
878
878
  });
879
879
  };
880
- BaseTrace.prototype.error = function (message, tag, extra) {
880
+ BaseTrace.prototype.error = function (message, extra, tag) {
881
881
  this.log({
882
882
  name: 'customer-error',
883
883
  type: TraceDataTypes.LOG,
@@ -1217,7 +1217,6 @@ var init = function (options) {
1217
1217
  return instance;
1218
1218
  }
1219
1219
  instance = TraceSdk.init(options);
1220
- console.log('instances: ', instance);
1221
1220
  return instance;
1222
1221
  };
1223
1222
  var getInstance = function () {