@hd-front-end/jsbridge-sdk 1.0.2 → 1.0.4

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 (26) hide show
  1. package/README.md +4 -2
  2. package/dist/index.d.ts +201 -2
  3. package/dist/index.esm.js +444 -1
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +446 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.umd.js +446 -0
  8. package/dist/index.umd.js.map +1 -1
  9. package/docs/00-/351/241/271/347/233/256/346/246/202/350/247/210.md +282 -0
  10. package/docs/01-/346/236/266/346/236/204/350/256/276/350/256/241.md +623 -0
  11. package/docs/02-/346/212/200/346/234/257/345/256/236/347/216/260.md +867 -0
  12. package/docs/03-API/344/275/277/347/224/250/346/226/207/346/241/243.md +1104 -0
  13. package/docs/04-/346/265/213/350/257/225/346/226/271/346/241/210.md +360 -0
  14. package/docs/05-/350/277/201/347/247/273/346/214/207/345/215/227.md +181 -0
  15. package/docs/06-/346/236/266/346/236/204/345/233/276/351/233/206.md +738 -0
  16. package/docs/07-/346/226/260/346/241/245/346/216/245/346/226/271/346/263/225/346/211/251/345/261/225/350/257/264/346/230/216.md +139 -0
  17. package/docs/CODE_REVIEW.md +65 -0
  18. package/docs/EVALUATION.md +72 -0
  19. package/docs/README.md +258 -0
  20. package/docs//345/205/263/351/224/256/351/227/256/351/242/230/350/247/243/347/255/224.md +495 -0
  21. package/docs//346/226/207/346/241/243/346/225/264/345/220/210/350/257/264/346/230/216.md +265 -0
  22. package/docs//346/233/264/346/226/260/346/227/245/345/277/227.md +669 -0
  23. package/docs//347/224/237/344/272/247/347/272/247-/345/277/253/351/200/237/345/274/200/345/247/213-v2.md +673 -0
  24. package/docs//347/224/237/344/272/247/347/272/247-/346/236/266/346/236/204/350/256/276/350/256/241-v2.md +730 -0
  25. package/docs//350/256/276/350/256/241/347/220/206/345/277/265/350/257/264/346/230/216.md +438 -0
  26. package/package.json +3 -2
@@ -0,0 +1,730 @@
1
+ # JSBridge SDK 生产级架构设计 v2
2
+
3
+ > **核心理念**:SDK 聚焦于 bridge API,通过原生 log 能力实现监控和日志上报
4
+
5
+ ## 🎯 设计原则
6
+
7
+ ### SDK 的核心职责
8
+
9
+ ✅ **必须做的**:
10
+ 1. 封装原生 WebView 通信(核心)
11
+ 2. **兼容 Android 和 iOS**(必需)
12
+ 3. **通过原生 log 能力实现监控**(生产必需)
13
+ 4. **提供 log API 给子应用**(功能必需)
14
+ 5. **提供 debug 模式**(开发必需)
15
+ 6. 完整的类型定义
16
+
17
+ ❌ **不做的**:
18
+ 1. uni API 适配层(子应用决定)
19
+ 2. 框架特定封装(Vue/React)
20
+ 3. 业务逻辑
21
+
22
+ ## 🏗️ 架构设计
23
+
24
+ ### 1. 整体架构
25
+
26
+ ```
27
+ ┌─────────────────────────────────────┐
28
+ │ 子应用 │
29
+ │ - 直接使用 SDK API │
30
+ │ - 可选封装适配层 │
31
+ │ - 调用 log API 上传业务日志 │
32
+ └─────────────────────────────────────┘
33
+
34
+ ┌─────────────────────────────────────┐
35
+ │ @hd-front-end/jsbridge-sdk │
36
+ │ │
37
+ │ ├── 核心通信层(Bridge) │
38
+ │ │ ├── Android 兼容 │
39
+ │ │ └── iOS 兼容 │
40
+ │ │ │
41
+ │ ├── API 层 │
42
+ │ │ ├── device.ts │
43
+ │ │ ├── media.ts │
44
+ │ │ ├── log.ts ← 新增 │
45
+ │ │ └── ... │
46
+ │ │ │
47
+ │ ├── 监控层(Monitor) │
48
+ │ │ ├── 性能监控 │
49
+ │ │ ├── 错误监控 │
50
+ │ │ ├── 调用统计 │
51
+ │ │ └── 通过原生 log 上报 ← 修改 │
52
+ │ │ │
53
+ │ └── 调试层(Debug) │
54
+ │ ├── vconsole 集成 │
55
+ │ ├── 日志输出 │
56
+ │ └── 调用追踪 │
57
+ └─────────────────────────────────────┘
58
+
59
+ ┌─────────────────────────────────────┐
60
+ │ 原生 WebView │
61
+ │ ├── Android (InjectJavascript) │
62
+ │ │ └── LogUtil (SLF4J+Logback) │
63
+ │ │ └── 写入日志文件 │
64
+ │ │ │
65
+ │ └── iOS (WKWebView) │
66
+ │ └── LogUtil (OSLog) │
67
+ │ └── 写入日志文件 │
68
+ └─────────────────────────────────────┘
69
+ ```
70
+
71
+ ## 💻 核心实现
72
+
73
+ ### 1. Log API(新增)
74
+
75
+ ```typescript
76
+ // src/api/log.ts
77
+ import { bridge } from '../core/Bridge'
78
+ import { monitor } from '../monitor/Monitor'
79
+ import { debug } from '../debug/Debug'
80
+
81
+ /**
82
+ * 日志级别
83
+ */
84
+ export enum LogLevel {
85
+ DEBUG = 'DEBUG',
86
+ INFO = 'INFO',
87
+ WARN = 'WARN',
88
+ ERROR = 'ERROR'
89
+ }
90
+
91
+ /**
92
+ * 日志请求参数
93
+ */
94
+ export interface LogRequest {
95
+ tag?: string // TAG 标识(可选)
96
+ level: LogLevel // 日志等级
97
+ message: string // 日志内容
98
+ }
99
+
100
+ /**
101
+ * 写日志到原生
102
+ * 日志会通过原生的 LogUtil 写入文件
103
+ */
104
+ export async function writeLog(request: LogRequest): Promise<void> {
105
+ // 记录监控
106
+ const record = monitor.recordStart('log', bridge.getPlatform(), request)
107
+
108
+ try {
109
+ // 调用原生 log handler
110
+ await bridge.call('log', {
111
+ tag: request.tag || 'JSBridge',
112
+ level: request.level,
113
+ message: request.message
114
+ })
115
+
116
+ // 记录成功
117
+ monitor.recordEnd(record, true)
118
+ debug.log('debug', `日志已写入: [${request.level}] ${request.message}`)
119
+
120
+ } catch (error) {
121
+ // 记录失败
122
+ monitor.recordEnd(record, false, undefined, (error as Error).message)
123
+ debug.log('error', `写入日志失败: ${(error as Error).message}`)
124
+ throw error
125
+ }
126
+ }
127
+
128
+ /**
129
+ * 便捷方法
130
+ */
131
+ export const log = {
132
+ debug: (message: string, tag?: string) =>
133
+ writeLog({ level: LogLevel.DEBUG, message, tag }),
134
+
135
+ info: (message: string, tag?: string) =>
136
+ writeLog({ level: LogLevel.INFO, message, tag }),
137
+
138
+ warn: (message: string, tag?: string) =>
139
+ writeLog({ level: LogLevel.WARN, message, tag }),
140
+
141
+ error: (message: string, tag?: string) =>
142
+ writeLog({ level: LogLevel.ERROR, message, tag })
143
+ }
144
+ ```
145
+
146
+ ### 2. 监控层(改为通过 log 上报)
147
+
148
+ ```typescript
149
+ // src/monitor/Monitor.ts
150
+ /**
151
+ * 监控配置
152
+ */
153
+ export interface MonitorConfig {
154
+ enabled: boolean
155
+ autoReport?: boolean // 自动上报
156
+ reportInterval?: number // 上报间隔(ms)
157
+ maxCacheSize?: number // 最大缓存条数
158
+ logTag?: string // 日志 TAG,默认 'JSBridge-Monitor'
159
+ }
160
+
161
+ /**
162
+ * 监控类
163
+ * 通过原生 log 能力上报监控数据
164
+ */
165
+ class Monitor {
166
+ private config: MonitorConfig
167
+ private records: ApiCallRecord[] = []
168
+ private stats: Map<string, PerformanceStats> = new Map()
169
+ private reportTimer?: NodeJS.Timeout
170
+
171
+ constructor(config: Partial<MonitorConfig> = {}) {
172
+ this.config = {
173
+ enabled: true,
174
+ reportInterval: 60000, // 默认 1 分钟
175
+ maxCacheSize: 100, // 默认缓存 100 条
176
+ autoReport: false, // 默认不自动上报
177
+ logTag: 'JSBridge-Monitor',
178
+ ...config
179
+ }
180
+
181
+ if (this.config.autoReport) {
182
+ this.startAutoReport()
183
+ }
184
+ }
185
+
186
+ /**
187
+ * 上报监控数据
188
+ * 通过原生 log 能力写入日志文件
189
+ */
190
+ async report(): Promise<void> {
191
+ if (this.records.length === 0) {
192
+ return
193
+ }
194
+
195
+ try {
196
+ const data = {
197
+ records: this.records,
198
+ stats: Array.from(this.stats.entries()).map(([api, stats]) => ({
199
+ api,
200
+ ...stats
201
+ })),
202
+ timestamp: Date.now()
203
+ }
204
+
205
+ // 通过原生 log 能力上报
206
+ await bridge.call('log', {
207
+ tag: this.config.logTag,
208
+ level: 'INFO',
209
+ message: `[MONITOR] ${JSON.stringify(data)}`
210
+ })
211
+
212
+ console.log('[Monitor] 监控数据已上报到原生日志')
213
+ this.clear()
214
+ } catch (error) {
215
+ console.error('[Monitor] 上报失败', error)
216
+ }
217
+ }
218
+
219
+ /**
220
+ * 上报错误信息
221
+ * 立即上报,不等待定时任务
222
+ */
223
+ async reportError(api: string, error: string, detail?: any): Promise<void> {
224
+ if (!this.config.enabled) {
225
+ return
226
+ }
227
+
228
+ try {
229
+ const errorData = {
230
+ type: 'error',
231
+ api,
232
+ error,
233
+ detail,
234
+ platform: bridge.getPlatform(),
235
+ timestamp: Date.now()
236
+ }
237
+
238
+ // 立即通过原生 log 能力上报错误
239
+ await bridge.call('log', {
240
+ tag: this.config.logTag,
241
+ level: 'ERROR',
242
+ message: `[ERROR] ${JSON.stringify(errorData)}`
243
+ })
244
+
245
+ console.error('[Monitor] 错误已上报:', errorData)
246
+ } catch (e) {
247
+ console.error('[Monitor] 上报错误失败', e)
248
+ }
249
+ }
250
+
251
+ // ... 其他方法保持不变
252
+ }
253
+
254
+ export const monitor = new Monitor()
255
+ ```
256
+
257
+ ### 3. Bridge 层集成 Log
258
+
259
+ ```typescript
260
+ // src/core/Bridge.ts
261
+ class Bridge {
262
+ // ... 其他代码
263
+
264
+ /**
265
+ * 调用原生方法(增强版)
266
+ */
267
+ async call<T = any>(method: string, data?: any): Promise<T> {
268
+ if (this.platform === Platform.Unknown) {
269
+ return Promise.reject(new Error('不在原生 App 环境中'))
270
+ }
271
+
272
+ if (!this.isInitialized) {
273
+ return Promise.reject(new Error('JSBridge 未初始化'))
274
+ }
275
+
276
+ // Debug: 追踪调用
277
+ debug.trace(method, data)
278
+
279
+ // Monitor: 开始记录
280
+ const record = monitor.recordStart(method, this.platform, data)
281
+
282
+ console.log(`[JSBridge] [${this.platform}] 调用: ${method}`, data)
283
+
284
+ return new Promise((resolve, reject) => {
285
+ try {
286
+ this.bridge.callHandler(method, data, (result: any) => {
287
+ console.log(`[JSBridge] [${this.platform}] 返回: ${method}`, result)
288
+
289
+ // Monitor: 记录成功
290
+ monitor.recordEnd(record, true, result)
291
+
292
+ // Debug: 记录日志
293
+ debug.log('info', `API 调用成功: ${method}`, { params: data, result })
294
+
295
+ resolve(result)
296
+ })
297
+ } catch (error) {
298
+ console.error(`[JSBridge] [${this.platform}] 调用失败: ${method}`, error)
299
+
300
+ // Monitor: 记录失败
301
+ monitor.recordEnd(record, false, undefined, (error as Error).message)
302
+
303
+ // Monitor: 立即上报错误(通过 log)
304
+ monitor.reportError(method, (error as Error).message, { params: data })
305
+
306
+ // Debug: 记录错误
307
+ debug.log('error', `API 调用失败: ${method}`, { params: data, error })
308
+
309
+ reject(error)
310
+ }
311
+ })
312
+ }
313
+ }
314
+ ```
315
+
316
+ ### 4. 统一导出
317
+
318
+ ```typescript
319
+ // src/index.ts
320
+ import { bridge, Platform } from './core/Bridge'
321
+ import { monitor, MonitorConfig } from './monitor/Monitor'
322
+ import { debug, DebugConfig } from './debug/Debug'
323
+ import * as device from './api/device'
324
+ import * as media from './api/media'
325
+ import * as router from './api/router'
326
+ import * as storage from './api/storage'
327
+ import * as system from './api/system'
328
+ import { writeLog, log, LogLevel, LogRequest } from './api/log' // 新增
329
+
330
+ /**
331
+ * SDK 配置
332
+ */
333
+ export interface JSBridgeConfig {
334
+ debug?: Partial<DebugConfig>
335
+ monitor?: Partial<MonitorConfig>
336
+ }
337
+
338
+ /**
339
+ * 初始化 JSBridge
340
+ */
341
+ export async function init(config?: JSBridgeConfig): Promise<boolean> {
342
+ try {
343
+ // 配置 debug
344
+ if (config?.debug) {
345
+ debug.updateConfig(config.debug)
346
+ if (config.debug.useVConsole) {
347
+ await debug.initVConsole()
348
+ }
349
+ }
350
+
351
+ // 配置 monitor
352
+ if (config?.monitor) {
353
+ monitor.updateConfig(config.monitor)
354
+ }
355
+
356
+ // 初始化 bridge
357
+ const success = await bridge.init()
358
+
359
+ // 保存平台信息
360
+ (window as any).__jsbridgePlatform = bridge.getPlatform()
361
+
362
+ // 通过 log API 记录初始化成功
363
+ if (success) {
364
+ await writeLog({
365
+ level: LogLevel.INFO,
366
+ message: `JSBridge 初始化成功 [${bridge.getPlatform()}]`
367
+ })
368
+ }
369
+
370
+ return success
371
+ } catch (error) {
372
+ console.error('[JSBridge] 初始化失败', error)
373
+ debug.log('error', '初始化失败', error)
374
+
375
+ // 尝试上报错误
376
+ try {
377
+ await writeLog({
378
+ level: LogLevel.ERROR,
379
+ message: `JSBridge 初始化失败: ${(error as Error).message}`
380
+ })
381
+ } catch (e) {
382
+ // 忽略上报失败
383
+ }
384
+
385
+ return false
386
+ }
387
+ }
388
+
389
+ /**
390
+ * JSBridge API
391
+ */
392
+ export const JSBridge = {
393
+ // 设备相关
394
+ scan: device.scan,
395
+ vibrate: device.vibrate,
396
+ getDeviceInfo: device.getDeviceInfo,
397
+ getNetworkType: device.getNetworkType,
398
+
399
+ // 媒体相关
400
+ chooseMedia: media.chooseMedia,
401
+ uploadFile: media.uploadFile,
402
+ previewImage: media.previewImage,
403
+ getImageInfo: media.getImageInfo,
404
+ bluetoothPrint: media.bluetoothPrint,
405
+
406
+ // 路由相关
407
+ setNavigationBar: router.setNavigationBar,
408
+ closeWebView: router.closeWebView,
409
+ onRoute: router.onRoute,
410
+ onGetRouteInfo: router.onGetRouteInfo,
411
+ notifyRouteChange: router.notifyRouteChange,
412
+
413
+ // 存储相关
414
+ getStorage: storage.getStorage,
415
+ setStorage: storage.setStorage,
416
+ getAppInfo: storage.getAppInfo,
417
+ onRefreshStore: storage.onRefreshStore,
418
+ notifyAppOnload: storage.notifyAppOnload,
419
+
420
+ // 系统相关
421
+ makePhoneCall: system.makePhoneCall,
422
+ onPdaScan: system.onPdaScan,
423
+
424
+ // 日志相关(新增)
425
+ writeLog, // 通用 log 方法
426
+ log // 便捷方法 { debug, info, warn, error }
427
+ }
428
+
429
+ /**
430
+ * 监控 API
431
+ */
432
+ export const Monitor = {
433
+ getStats: monitor.getStats.bind(monitor),
434
+ getRecords: monitor.getRecords.bind(monitor),
435
+ clear: monitor.clear.bind(monitor),
436
+ report: monitor.report.bind(monitor), // 手动上报(通过 log)
437
+ reportError: monitor.reportError.bind(monitor) // 上报错误(通过 log)
438
+ }
439
+
440
+ /**
441
+ * Debug API
442
+ */
443
+ export const Debug = {
444
+ trace: debug.trace.bind(debug),
445
+ getLogs: debug.getLogs.bind(debug),
446
+ clearLogs: debug.clearLogs.bind(debug)
447
+ }
448
+
449
+ // 导出类型
450
+ export * from './types'
451
+ export { Platform, MonitorConfig, DebugConfig, LogLevel, LogRequest }
452
+ ```
453
+
454
+ ## 📚 使用示例
455
+
456
+ ### 1. 子应用使用 log API
457
+
458
+ ```typescript
459
+ import { JSBridge, LogLevel } from '@hd-front-end/jsbridge-sdk'
460
+
461
+ // 方式 1:使用通用方法
462
+ await JSBridge.writeLog({
463
+ level: LogLevel.INFO,
464
+ message: '用户点击了购买按钮',
465
+ tag: 'ShoppingCart'
466
+ })
467
+
468
+ // 方式 2:使用便捷方法
469
+ await JSBridge.log.info('用户点击了购买按钮', 'ShoppingCart')
470
+ await JSBridge.log.error('支付失败', 'Payment')
471
+ await JSBridge.log.warn('库存不足', 'Inventory')
472
+ await JSBridge.log.debug('调试信息', 'Debug')
473
+ ```
474
+
475
+ ### 2. 监控数据通过 log 上报
476
+
477
+ ```typescript
478
+ import { init, Monitor } from '@hd-front-end/jsbridge-sdk'
479
+
480
+ // 初始化时配置监控
481
+ await init({
482
+ monitor: {
483
+ enabled: true,
484
+ autoReport: true, // 自动上报
485
+ reportInterval: 60000, // 1 分钟上报一次
486
+ logTag: 'JSBridge-Monitor' // 日志 TAG
487
+ }
488
+ })
489
+
490
+ // 使用 API(自动监控)
491
+ await JSBridge.scan()
492
+
493
+ // 监控数据会自动通过原生 log 能力写入日志文件
494
+ // 原生端可以统一收集这些日志文件上传到服务器
495
+ ```
496
+
497
+ ### 3. 错误立即上报
498
+
499
+ ```typescript
500
+ import { JSBridge, Monitor } from '@hd-front-end/jsbridge-sdk'
501
+
502
+ try {
503
+ await JSBridge.scan()
504
+ } catch (error) {
505
+ // SDK 会自动上报错误
506
+ // 也可以手动上报额外信息
507
+ await Monitor.reportError('scan', error.message, {
508
+ userAction: '用户尝试扫码',
509
+ currentPage: '/product-detail'
510
+ })
511
+ }
512
+ ```
513
+
514
+ ### 4. 业务日志上报
515
+
516
+ ```typescript
517
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
518
+
519
+ // 记录用户行为
520
+ await JSBridge.log.info('用户进入商品详情页', 'UserBehavior')
521
+
522
+ // 记录业务错误
523
+ await JSBridge.log.error('订单创建失败: 库存不足', 'OrderService')
524
+
525
+ // 记录性能数据
526
+ await JSBridge.log.info(`页面加载耗时: ${loadTime}ms`, 'Performance')
527
+
528
+ // 记录调试信息
529
+ await JSBridge.log.debug(`API 响应: ${JSON.stringify(response)}`, 'API')
530
+ ```
531
+
532
+ ## 🔄 日志流程
533
+
534
+ ### 1. SDK 监控日志流程
535
+
536
+ ```
537
+ SDK API 调用
538
+
539
+ Monitor 记录性能数据
540
+
541
+ 定时任务触发(1 分钟)
542
+
543
+ Monitor.report()
544
+
545
+ 调用 bridge.call('log', {...})
546
+
547
+ 原生 LogUtil 写入日志文件
548
+
549
+ 原生统一收集上传到服务器
550
+ ```
551
+
552
+ ### 2. 子应用业务日志流程
553
+
554
+ ```
555
+ 子应用调用 JSBridge.log.info(...)
556
+
557
+ SDK log API
558
+
559
+ 调用 bridge.call('log', {...})
560
+
561
+ 原生 LogUtil 写入日志文件
562
+
563
+ 原生统一收集上传到服务器
564
+ ```
565
+
566
+ ### 3. 错误日志流程(立即上报)
567
+
568
+ ```
569
+ API 调用失败
570
+
571
+ Monitor.reportError()
572
+
573
+ 立即调用 bridge.call('log', {level: 'ERROR', ...})
574
+
575
+ 原生 LogUtil 写入日志文件(ERROR 级别)
576
+
577
+ 原生可以立即上传 ERROR 日志
578
+ ```
579
+
580
+ ## 📊 原生端实现参考
581
+
582
+ ### Android (Kotlin)
583
+
584
+ ```kotlin
585
+ // 原生端 log handler 注册
586
+ webView.registerHandler("log") { data, callback ->
587
+ val request = Gson().fromJson(data, UniLog::class.java)
588
+
589
+ // 使用 LogUtil 写入日志
590
+ when (request.level) {
591
+ "DEBUG" -> LogUtil.debug(request.tag, request.message)
592
+ "INFO" -> LogUtil.info(request.tag, request.message)
593
+ "WARN" -> LogUtil.warn(request.tag, request.message)
594
+ "ERROR" -> LogUtil.error(request.tag, request.message)
595
+ }
596
+
597
+ callback?.invoke(null)
598
+ }
599
+
600
+ // LogUtil 会通过 SLF4J + Logback 写入文件
601
+ // 配置在 logback.xml 中
602
+ ```
603
+
604
+ ### iOS (Swift)
605
+
606
+ ```swift
607
+ // 原生端 log handler 注册
608
+ bridge.registerHandler("log") { data, callback in
609
+ guard let request = data as? [String: Any],
610
+ let level = request["level"] as? String,
611
+ let message = request["message"] as? String else {
612
+ callback?(nil)
613
+ return
614
+ }
615
+
616
+ let tag = request["tag"] as? String ?? "JSBridge"
617
+
618
+ // 使用 OSLog 写入日志
619
+ switch level {
620
+ case "DEBUG":
621
+ os_log(.debug, log: OSLog(subsystem: "JSBridge", category: tag), "%{public}@", message)
622
+ case "INFO":
623
+ os_log(.info, log: OSLog(subsystem: "JSBridge", category: tag), "%{public}@", message)
624
+ case "WARN":
625
+ os_log(.error, log: OSLog(subsystem: "JSBridge", category: tag), "[WARN] %{public}@", message)
626
+ case "ERROR":
627
+ os_log(.fault, log: OSLog(subsystem: "JSBridge", category: tag), "%{public}@", message)
628
+ default:
629
+ break
630
+ }
631
+
632
+ callback?(nil)
633
+ }
634
+ ```
635
+
636
+ ## 📊 目录结构
637
+
638
+ ```
639
+ @hd-front-end/jsbridge-sdk/
640
+ ├── src/
641
+ │ ├── core/
642
+ │ │ └── Bridge.ts # 核心通信(200 行)
643
+ │ │
644
+ │ ├── monitor/
645
+ │ │ └── Monitor.ts # 监控(改用 log 上报)
646
+ │ │
647
+ │ ├── debug/
648
+ │ │ └── Debug.ts # Debug 模式
649
+ │ │
650
+ │ ├── api/
651
+ │ │ ├── device.ts
652
+ │ │ ├── media.ts
653
+ │ │ ├── router.ts
654
+ │ │ ├── storage.ts
655
+ │ │ ├── system.ts
656
+ │ │ └── log.ts # ← 新增 log API
657
+ │ │
658
+ │ ├── types/
659
+ │ │ └── index.ts
660
+ │ │
661
+ │ └── index.ts # 统一导出
662
+
663
+ └── package.json
664
+ ```
665
+
666
+ ## 💡 核心价值
667
+
668
+ ### 1. 统一日志管理
669
+
670
+ ✅ **SDK 监控日志** - 通过 log 写入原生
671
+ ✅ **子应用业务日志** - 通过 log API 写入原生
672
+ ✅ **统一收集** - 原生统一管理日志文件
673
+ ✅ **统一上传** - 原生统一上传到服务器
674
+
675
+ ### 2. 两个目的都实现
676
+
677
+ ✅ **监控 SDK 稳定性**
678
+ - SDK 内部自动记录性能数据
679
+ - 定时通过 log 上报
680
+ - 错误立即通过 log 上报
681
+ - 原生收集后可分析 SDK 调用情况
682
+
683
+ ✅ **提供子应用上传日志能力**
684
+ - 子应用调用 `JSBridge.log.*` 方法
685
+ - 日志通过 bridge 写入原生
686
+ - 原生统一管理和上传
687
+ - 子应用无需关心上传细节
688
+
689
+ ### 3. 优势
690
+
691
+ ✅ **统一管理** - 所有日志都通过原生 LogUtil
692
+ ✅ **性能更好** - 不需要 H5 端发起 HTTP 请求
693
+ ✅ **更可靠** - 原生端控制上传时机和策略
694
+ ✅ **易于扩展** - 原生可以灵活处理日志(压缩、加密、批量上传等)
695
+
696
+ ## 📊 代码统计
697
+
698
+ | 模块 | 文件 | 代码行数 |
699
+ |------|------|---------|
700
+ | 核心通信(兼容) | Bridge.ts | 200 行 |
701
+ | 监控(改用 log) | Monitor.ts | 180 行 |
702
+ | Debug | Debug.ts | 150 行 |
703
+ | Log API(新增) | log.ts | 80 行 |
704
+ | 其他 API | 5 个文件 | 320 行 |
705
+ | 类型定义 | types/index.ts | 120 行 |
706
+ | 统一导出 | index.ts | 100 行 |
707
+ | **总计** | **11 个文件** | **~1150 行** |
708
+
709
+ 打包体积:~20KB(gzip: ~7KB)
710
+
711
+ ## 🎯 总结
712
+
713
+ ### 核心改进
714
+
715
+ 1. ✅ **监控数据通过 log 上报** - 不再使用 HTTP
716
+ 2. ✅ **提供 log API** - 子应用可以上传日志
717
+ 3. ✅ **统一日志管理** - 原生端统一处理
718
+ 4. ✅ **两个目的都实现** - 监控 SDK + 子应用日志
719
+
720
+ ### 设计理念不变
721
+
722
+ - SDK 聚焦于 bridge API
723
+ - 不包含适配层
724
+ - 兼容 Android/iOS
725
+ - 简洁实用
726
+
727
+ ---
728
+
729
+ **统一日志,统一管理,简洁高效** 🎯
730
+