@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,673 @@
1
+ # JSBridge SDK 生产级 - 快速开始 v2
2
+
3
+ > **兼容 Android/iOS,内置监控和 debug 模式,通过原生 log 能力上报数据**
4
+
5
+ ## 📦 安装
6
+
7
+ ```bash
8
+ npm install @hd-front-end/jsbridge-sdk
9
+
10
+ # 开发环境需要 vconsole
11
+ npm install --save-dev vconsole
12
+ ```
13
+
14
+ ## 🚀 快速开始
15
+
16
+ ### 1. 基础使用
17
+
18
+ ```typescript
19
+ import { init, JSBridge } from '@hd-front-end/jsbridge-sdk'
20
+
21
+ // 初始化
22
+ await init()
23
+
24
+ // 使用 API
25
+ const result = await JSBridge.scan()
26
+ console.log(result.resp_result)
27
+ ```
28
+
29
+ ### 2. 开发环境配置(推荐)
30
+
31
+ ```typescript
32
+ import { init, JSBridge, Debug } from '@hd-front-end/jsbridge-sdk'
33
+
34
+ // 开发环境:启用 debug 和 vconsole
35
+ await init({
36
+ debug: {
37
+ enabled: true,
38
+ useVConsole: true,
39
+ logLevel: 'debug'
40
+ },
41
+ monitor: {
42
+ enabled: false // 开发环境不需要监控
43
+ }
44
+ })
45
+ ```
46
+
47
+ ### 3. 生产环境配置(推荐)
48
+
49
+ ```typescript
50
+ import { init, JSBridge, Monitor } from '@hd-front-end/jsbridge-sdk'
51
+
52
+ // 生产环境:启用监控(通过原生 log 上报)
53
+ await init({
54
+ debug: {
55
+ enabled: false
56
+ },
57
+ monitor: {
58
+ enabled: true,
59
+ autoReport: true, // 自动上报到原生 log
60
+ reportInterval: 60000, // 1 分钟上报一次
61
+ logTag: 'JSBridge-Monitor' // 日志 TAG
62
+ }
63
+ })
64
+
65
+ // 监控数据会自动通过原生 log 能力写入日志文件
66
+ // 原生端统一收集并上传到服务器
67
+ ```
68
+
69
+ ### 4. 根据环境自动配置(最佳实践)
70
+
71
+ ```typescript
72
+ import { init } from '@hd-front-end/jsbridge-sdk'
73
+
74
+ const isDev = process.env.NODE_ENV === 'development'
75
+
76
+ await init({
77
+ debug: {
78
+ enabled: isDev,
79
+ useVConsole: isDev,
80
+ logLevel: isDev ? 'debug' : 'error'
81
+ },
82
+ monitor: {
83
+ enabled: !isDev, // 生产环境启用
84
+ autoReport: !isDev, // 生产环境自动上报
85
+ reportInterval: 60000,
86
+ logTag: 'JSBridge-Monitor'
87
+ }
88
+ })
89
+ ```
90
+
91
+ ## 📝 Log API 使用(新增)
92
+
93
+ ### 1. 基础使用
94
+
95
+ ```typescript
96
+ import { JSBridge, LogLevel } from '@hd-front-end/jsbridge-sdk'
97
+
98
+ // 方式 1:使用通用方法
99
+ await JSBridge.writeLog({
100
+ level: LogLevel.INFO,
101
+ message: '用户点击了购买按钮',
102
+ tag: 'ShoppingCart'
103
+ })
104
+
105
+ // 方式 2:使用便捷方法(推荐)
106
+ await JSBridge.log.info('用户点击了购买按钮', 'ShoppingCart')
107
+ await JSBridge.log.error('支付失败', 'Payment')
108
+ await JSBridge.log.warn('库存不足', 'Inventory')
109
+ await JSBridge.log.debug('调试信息', 'Debug')
110
+ ```
111
+
112
+ ### 2. 记录用户行为
113
+
114
+ ```typescript
115
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
116
+
117
+ // 进入页面
118
+ await JSBridge.log.info('用户进入商品详情页', 'UserBehavior')
119
+
120
+ // 点击按钮
121
+ await JSBridge.log.info('用户点击了加入购物车', 'UserBehavior')
122
+
123
+ // 完成操作
124
+ await JSBridge.log.info('用户完成了支付', 'UserBehavior')
125
+ ```
126
+
127
+ ### 3. 记录业务错误
128
+
129
+ ```typescript
130
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
131
+
132
+ try {
133
+ // 业务逻辑
134
+ await createOrder()
135
+ } catch (error) {
136
+ // 记录业务错误
137
+ await JSBridge.log.error(
138
+ `订单创建失败: ${error.message}`,
139
+ 'OrderService'
140
+ )
141
+ }
142
+ ```
143
+
144
+ ### 4. 记录性能数据
145
+
146
+ ```typescript
147
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
148
+
149
+ const startTime = Date.now()
150
+
151
+ // 执行操作
152
+ await loadData()
153
+
154
+ const duration = Date.now() - startTime
155
+
156
+ // 记录性能数据
157
+ await JSBridge.log.info(
158
+ `页面加载耗时: ${duration}ms`,
159
+ 'Performance'
160
+ )
161
+ ```
162
+
163
+ ### 5. 记录 API 调用
164
+
165
+ ```typescript
166
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
167
+
168
+ // 请求前
169
+ await JSBridge.log.debug('开始请求商品列表', 'API')
170
+
171
+ try {
172
+ const response = await fetch('/api/products')
173
+
174
+ // 请求成功
175
+ await JSBridge.log.debug(
176
+ `请求成功: ${response.data.length} 条数据`,
177
+ 'API'
178
+ )
179
+ } catch (error) {
180
+ // 请求失败
181
+ await JSBridge.log.error(
182
+ `请求失败: ${error.message}`,
183
+ 'API'
184
+ )
185
+ }
186
+ ```
187
+
188
+ ## 📚 核心 API
189
+
190
+ ### 设备能力
191
+
192
+ ```typescript
193
+ // 扫码
194
+ const result = await JSBridge.scan()
195
+
196
+ // 选择媒体
197
+ const media = await JSBridge.chooseMedia({ count: 1 })
198
+
199
+ // 上传文件
200
+ const uploadResult = await JSBridge.uploadFile({
201
+ url: 'https://api.example.com/upload',
202
+ filePath: media.tempFilePaths[0],
203
+ name: 'file'
204
+ })
205
+
206
+ // 获取设备信息
207
+ const deviceInfo = await JSBridge.getDeviceInfo()
208
+ ```
209
+
210
+ ### 日志能力(新增)
211
+
212
+ ```typescript
213
+ // 写日志
214
+ await JSBridge.log.info('日志内容', 'TAG')
215
+ await JSBridge.log.error('错误信息', 'TAG')
216
+ await JSBridge.log.warn('警告信息', 'TAG')
217
+ await JSBridge.log.debug('调试信息', 'TAG')
218
+
219
+ // 通用方法
220
+ await JSBridge.writeLog({
221
+ level: LogLevel.INFO,
222
+ message: '日志内容',
223
+ tag: 'TAG'
224
+ })
225
+ ```
226
+
227
+ ### 监控 API
228
+
229
+ ```typescript
230
+ import { Monitor } from '@hd-front-end/jsbridge-sdk'
231
+
232
+ // 获取统计
233
+ const stats = Monitor.getStats('scan')
234
+
235
+ // 获取记录
236
+ const records = Monitor.getRecords(10)
237
+
238
+ // 手动上报(通过 log)
239
+ await Monitor.report()
240
+
241
+ // 上报错误(立即通过 log)
242
+ await Monitor.reportError('scan', '扫码失败', { detail: '...' })
243
+ ```
244
+
245
+ ### Debug API
246
+
247
+ ```typescript
248
+ import { Debug } from '@hd-front-end/jsbridge-sdk'
249
+
250
+ // 追踪调用
251
+ Debug.trace('scan', { scanType: ['qrCode'] })
252
+
253
+ // 获取日志
254
+ const logs = Debug.getLogs('error', 10)
255
+
256
+ // 清空日志
257
+ Debug.clearLogs()
258
+ ```
259
+
260
+ ## 📊 监控和日志流程
261
+
262
+ ### 1. SDK 自动监控
263
+
264
+ ```
265
+ SDK API 调用(如 scan)
266
+
267
+ 自动记录性能数据
268
+
269
+ 定时任务(1 分钟)
270
+
271
+ 通过 log API 上报到原生
272
+
273
+ 原生 LogUtil 写入日志文件
274
+
275
+ 原生统一收集上传到服务器
276
+ ```
277
+
278
+ ### 2. 子应用主动上传日志
279
+
280
+ ```
281
+ 子应用调用 JSBridge.log.info(...)
282
+
283
+ SDK log API
284
+
285
+ 通过 bridge 调用原生 log handler
286
+
287
+ 原生 LogUtil 写入日志文件
288
+
289
+ 原生统一收集上传到服务器
290
+ ```
291
+
292
+ ### 3. 错误立即上报
293
+
294
+ ```
295
+ API 调用失败
296
+
297
+ SDK 捕获错误
298
+
299
+ 立即通过 log API 上报(ERROR 级别)
300
+
301
+ 原生可以立即上传 ERROR 日志
302
+ ```
303
+
304
+ ## 🎯 完整示例
305
+
306
+ ### App.vue
307
+
308
+ ```typescript
309
+ import { init, JSBridge, getPlatform } from '@hd-front-end/jsbridge-sdk'
310
+
311
+ const isDev = process.env.NODE_ENV === 'development'
312
+
313
+ export default {
314
+ async onLaunch() {
315
+ // #ifdef H5-HD
316
+ await this.initJSBridge()
317
+ // #endif
318
+ },
319
+
320
+ methods: {
321
+ async initJSBridge() {
322
+ try {
323
+ // 初始化配置
324
+ const success = await init({
325
+ debug: {
326
+ enabled: isDev,
327
+ useVConsole: isDev && /vconsole=true/.test(location.search),
328
+ logLevel: isDev ? 'debug' : 'error'
329
+ },
330
+ monitor: {
331
+ enabled: !isDev,
332
+ autoReport: !isDev,
333
+ reportInterval: 60000,
334
+ logTag: 'JSBridge-Monitor'
335
+ }
336
+ })
337
+
338
+ if (!success) {
339
+ console.warn('JSBridge 初始化失败')
340
+ return
341
+ }
342
+
343
+ const platform = getPlatform()
344
+ console.log(`JSBridge 初始化成功 [${platform}]`)
345
+
346
+ // 记录日志
347
+ await JSBridge.log.info(
348
+ `App 启动成功 [${platform}]`,
349
+ 'AppLifeCycle'
350
+ )
351
+
352
+ // 注册原生回调
353
+ this.setupBridgeHandlers()
354
+
355
+ } catch (error) {
356
+ console.error('JSBridge 初始化异常:', error)
357
+
358
+ // 上报错误
359
+ try {
360
+ await JSBridge.log.error(
361
+ `初始化失败: ${error.message}`,
362
+ 'AppLifeCycle'
363
+ )
364
+ } catch (e) {
365
+ // 忽略
366
+ }
367
+ }
368
+ }
369
+ }
370
+ }
371
+ ```
372
+
373
+ ### 业务组件
374
+
375
+ ```vue
376
+ <template>
377
+ <view class="page">
378
+ <button @click="handleScan">扫码</button>
379
+ <button @click="handleUploadLog">上传日志</button>
380
+ </view>
381
+ </template>
382
+
383
+ <script>
384
+ import { JSBridge, inApp, Monitor } from '@hd-front-end/jsbridge-sdk'
385
+
386
+ export default {
387
+ methods: {
388
+ async handleScan() {
389
+ if (!inApp()) {
390
+ uni.showToast({ title: '请在 App 中使用', icon: 'none' })
391
+ return
392
+ }
393
+
394
+ // 记录用户行为
395
+ await JSBridge.log.info('用户点击扫码按钮', 'UserBehavior')
396
+
397
+ try {
398
+ const result = await JSBridge.scan({
399
+ scanType: ['qrCode']
400
+ })
401
+
402
+ if (result.resp_code === 1000) {
403
+ // 记录成功
404
+ await JSBridge.log.info(
405
+ `扫码成功: ${result.resp_result}`,
406
+ 'ScanResult'
407
+ )
408
+
409
+ uni.showToast({ title: '扫码成功', icon: 'success' })
410
+ }
411
+ } catch (error) {
412
+ // 记录错误(SDK 会自动上报,这里是业务日志)
413
+ await JSBridge.log.error(
414
+ `扫码失败: ${error.message}`,
415
+ 'ScanError'
416
+ )
417
+
418
+ uni.showToast({ title: '扫码失败', icon: 'error' })
419
+ }
420
+ },
421
+
422
+ async handleUploadLog() {
423
+ try {
424
+ // 手动触发监控数据上报
425
+ await Monitor.report()
426
+
427
+ // 也可以上传自定义日志
428
+ await JSBridge.log.info(
429
+ '用户手动触发日志上传',
430
+ 'UserAction'
431
+ )
432
+
433
+ uni.showToast({ title: '日志已上传', icon: 'success' })
434
+ } catch (error) {
435
+ uni.showToast({ title: '上传失败', icon: 'error' })
436
+ }
437
+ }
438
+ }
439
+ }
440
+ </script>
441
+ ```
442
+
443
+ ### 页面生命周期日志
444
+
445
+ ```typescript
446
+ export default {
447
+ async onLoad() {
448
+ // 记录页面加载
449
+ await JSBridge.log.info('进入商品详情页', 'PageLifeCycle')
450
+ },
451
+
452
+ async onShow() {
453
+ const startTime = Date.now()
454
+
455
+ // 加载数据
456
+ await this.loadData()
457
+
458
+ const duration = Date.now() - startTime
459
+
460
+ // 记录性能
461
+ await JSBridge.log.info(
462
+ `页面数据加载耗时: ${duration}ms`,
463
+ 'Performance'
464
+ )
465
+ },
466
+
467
+ async onUnload() {
468
+ // 记录页面卸载
469
+ await JSBridge.log.info('离开商品详情页', 'PageLifeCycle')
470
+ }
471
+ }
472
+ ```
473
+
474
+ ## 🔧 高级用法
475
+
476
+ ### 1. 封装统一的日志工具
477
+
478
+ ```typescript
479
+ // utils/logger.ts
480
+ import { JSBridge, LogLevel } from '@hd-front-end/jsbridge-sdk'
481
+
482
+ export const Logger = {
483
+ // 用户行为
484
+ behavior(action: string, detail?: any) {
485
+ return JSBridge.log.info(
486
+ `[行为] ${action}${detail ? ': ' + JSON.stringify(detail) : ''}`,
487
+ 'UserBehavior'
488
+ )
489
+ },
490
+
491
+ // 业务错误
492
+ businessError(module: string, error: string, detail?: any) {
493
+ return JSBridge.log.error(
494
+ `[${module}] ${error}${detail ? ': ' + JSON.stringify(detail) : ''}`,
495
+ 'BusinessError'
496
+ )
497
+ },
498
+
499
+ // 性能数据
500
+ performance(metric: string, duration: number) {
501
+ return JSBridge.log.info(
502
+ `[性能] ${metric}: ${duration}ms`,
503
+ 'Performance'
504
+ )
505
+ },
506
+
507
+ // API 调用
508
+ api(method: string, url: string, duration: number, success: boolean) {
509
+ return JSBridge.log.info(
510
+ `[API] ${method} ${url} ${duration}ms ${success ? '成功' : '失败'}`,
511
+ 'API'
512
+ )
513
+ }
514
+ }
515
+
516
+ // 使用
517
+ await Logger.behavior('点击购买按钮', { productId: '123' })
518
+ await Logger.businessError('订单', '创建失败', { reason: '库存不足' })
519
+ await Logger.performance('页面加载', 1234)
520
+ await Logger.api('GET', '/api/products', 567, true)
521
+ ```
522
+
523
+ ### 2. 监控拦截器
524
+
525
+ ```typescript
526
+ // utils/request.ts
527
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
528
+
529
+ // 请求拦截器
530
+ axios.interceptors.request.use(async (config) => {
531
+ // 记录请求开始
532
+ config.metadata = { startTime: Date.now() }
533
+
534
+ await JSBridge.log.debug(
535
+ `请求开始: ${config.method} ${config.url}`,
536
+ 'API'
537
+ )
538
+
539
+ return config
540
+ })
541
+
542
+ // 响应拦截器
543
+ axios.interceptors.response.use(
544
+ async (response) => {
545
+ const duration = Date.now() - response.config.metadata.startTime
546
+
547
+ // 记录成功
548
+ await JSBridge.log.info(
549
+ `请求成功: ${response.config.method} ${response.config.url} ${duration}ms`,
550
+ 'API'
551
+ )
552
+
553
+ return response
554
+ },
555
+ async (error) => {
556
+ const duration = Date.now() - error.config.metadata.startTime
557
+
558
+ // 记录失败
559
+ await JSBridge.log.error(
560
+ `请求失败: ${error.config.method} ${error.config.url} ${duration}ms - ${error.message}`,
561
+ 'API'
562
+ )
563
+
564
+ return Promise.reject(error)
565
+ }
566
+ )
567
+ ```
568
+
569
+ ### 3. 错误边界
570
+
571
+ ```typescript
572
+ // App.vue
573
+ import { JSBridge } from '@hd-front-end/jsbridge-sdk'
574
+
575
+ export default {
576
+ onError(err) {
577
+ // 全局错误捕获
578
+ console.error('全局错误:', err)
579
+
580
+ // 上报错误
581
+ JSBridge.log.error(
582
+ `未捕获的错误: ${err.message}\n${err.stack}`,
583
+ 'GlobalError'
584
+ )
585
+ },
586
+
587
+ onUnhandledRejection(reason) {
588
+ // Promise 未处理的 rejection
589
+ console.error('Promise rejection:', reason)
590
+
591
+ // 上报错误
592
+ JSBridge.log.error(
593
+ `未处理的 Promise rejection: ${reason}`,
594
+ 'GlobalError'
595
+ )
596
+ }
597
+ }
598
+ ```
599
+
600
+ ## ❓ 常见问题
601
+
602
+ ### Q1: 日志会影响性能吗?
603
+
604
+ **A:** 不会。日志调用是异步的,不会阻塞主线程。原生端负责日志的写入和上传。
605
+
606
+ ### Q2: 日志什么时候上传?
607
+
608
+ **A:**
609
+ - SDK 监控日志:定时上报(默认 1 分钟)
610
+ - 错误日志:立即上报
611
+ - 业务日志:写入后由原生统一管理和上传
612
+
613
+ ### Q3: 如何控制日志量?
614
+
615
+ **A:**
616
+ - 生产环境只记录 INFO 及以上级别
617
+ - 使用合适的 TAG 分类
618
+ - 原生端可以配置日志上传策略
619
+
620
+ ### Q4: 如何查看日志?
621
+
622
+ **A:**
623
+ - 开发环境:通过 vconsole 查看
624
+ - 原生端:日志文件在 `logDir` 目录
625
+ - 服务器:原生上传后可在服务器查看
626
+
627
+ ### Q5: TAG 怎么命名?
628
+
629
+ **A:** 建议规范:
630
+ - `UserBehavior` - 用户行为
631
+ - `Performance` - 性能数据
632
+ - `API` - API 调用
633
+ - `BusinessError` - 业务错误
634
+ - `PageLifeCycle` - 页面生命周期
635
+ - 或使用模块名:`ShoppingCart`, `Payment`, `OrderService` 等
636
+
637
+ ## 📚 更多文档
638
+
639
+ - [架构设计 v2](./生产级-架构设计-v2.md) - 完整架构说明
640
+ - [监控指南](./监控指南.md) - 监控最佳实践
641
+ - [设计理念](./设计理念说明.md) - 为什么这样设计
642
+
643
+ ## 🎯 核心优势
644
+
645
+ ### 1. 统一日志管理
646
+
647
+ ✅ SDK 监控日志自动上报
648
+ ✅ 子应用可以主动上传日志
649
+ ✅ 原生统一管理和上传
650
+ ✅ 服务器统一收集分析
651
+
652
+ ### 2. 两个目的都实现
653
+
654
+ ✅ **监控 SDK 稳定性**
655
+ - SDK 自动记录性能和错误
656
+ - 定时/立即上报到原生
657
+ - 服务器可分析 SDK 运行状况
658
+
659
+ ✅ **提供子应用日志能力**
660
+ - 子应用调用简单的 log API
661
+ - 日志自动写入原生
662
+ - 无需关心上传细节
663
+
664
+ ### 3. 简单易用
665
+
666
+ ✅ **初始化简单** - 一次配置,自动运行
667
+ ✅ **API 简单** - `JSBridge.log.info(...)` 即可
668
+ ✅ **无需关心细节** - 原生负责日志管理和上传
669
+
670
+ ---
671
+
672
+ **统一日志,简单易用** 🎯
673
+