@hd-front-end/jsbridge-sdk 1.0.2 → 1.0.3
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 +4 -2
- package/dist/index.d.ts +204 -2
- package/dist/index.esm.js +446 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +448 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +450 -4
- package/dist/index.umd.js.map +1 -1
- package/docs/00-/351/241/271/347/233/256/346/246/202/350/247/210.md +282 -0
- package/docs/01-/346/236/266/346/236/204/350/256/276/350/256/241.md +623 -0
- package/docs/02-/346/212/200/346/234/257/345/256/236/347/216/260.md +867 -0
- package/docs/03-API/344/275/277/347/224/250/346/226/207/346/241/243.md +1104 -0
- package/docs/04-/346/265/213/350/257/225/346/226/271/346/241/210.md +360 -0
- package/docs/05-/350/277/201/347/247/273/346/214/207/345/215/227.md +181 -0
- package/docs/06-/346/236/266/346/236/204/345/233/276/351/233/206.md +738 -0
- 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
- package/docs/CODE_REVIEW.md +65 -0
- package/docs/EVALUATION.md +72 -0
- package/docs/README.md +258 -0
- package/docs//345/205/263/351/224/256/351/227/256/351/242/230/350/247/243/347/255/224.md +495 -0
- package/docs//346/226/207/346/241/243/346/225/264/345/220/210/350/257/264/346/230/216.md +265 -0
- package/docs//346/233/264/346/226/260/346/227/245/345/277/227.md +669 -0
- 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
- 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
- package/docs//350/256/276/350/256/241/347/220/206/345/277/265/350/257/264/346/230/216.md +438 -0
- package/package.json +3 -2
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# JSBridge SDK 设计理念说明
|
|
2
|
+
|
|
3
|
+
## 📝 设计演进过程
|
|
4
|
+
|
|
5
|
+
### v1 版本:过度设计
|
|
6
|
+
|
|
7
|
+
**错误理解**:SDK 应该解决所有问题
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
SDK = 核心通信 + 框架适配 (Vue2/Vue3/React) + 监控系统
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**问题**:
|
|
14
|
+
- ❌ 支持过多框架(React、独立 Vue3)
|
|
15
|
+
- ❌ 包含复杂的监控系统
|
|
16
|
+
- ❌ 过度设计(6 层架构)
|
|
17
|
+
- ❌ 学习成本高,维护成本高
|
|
18
|
+
|
|
19
|
+
### v2 版本:加入适配层(仍然错误)
|
|
20
|
+
|
|
21
|
+
**错误理解**:SDK 应该包含 uni API 适配层
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
SDK = 核心通信 + uni API 适配层 (hdAppAdapter)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**问题**:
|
|
28
|
+
- ❌ 把适配层当成 SDK 的一部分
|
|
29
|
+
- ❌ 强制子应用使用 uni API
|
|
30
|
+
- ❌ 处理 Vue2/Vue3 差异
|
|
31
|
+
- ❌ 绑定 uni-app 框架
|
|
32
|
+
|
|
33
|
+
### 最终版:回归本质(正确!)
|
|
34
|
+
|
|
35
|
+
**正确理解**:SDK 只提供原生 API 封装
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
SDK = 纯粹的原生 API 封装
|
|
39
|
+
适配层 = 子应用的选择(不是 SDK 的一部分)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**优势**:
|
|
43
|
+
- ✅ 职责单一:只封装原生通信
|
|
44
|
+
- ✅ 无框架依赖:纯 JavaScript
|
|
45
|
+
- ✅ 使用灵活:子应用自己决定如何使用
|
|
46
|
+
- ✅ 易于维护:代码简洁,逻辑清晰
|
|
47
|
+
|
|
48
|
+
## 🎯 核心设计理念
|
|
49
|
+
|
|
50
|
+
### 理念 1:职责单一
|
|
51
|
+
|
|
52
|
+
**SDK 的唯一职责**:封装原生 WebView 通信能力
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// ✅ SDK 应该做的
|
|
56
|
+
class Bridge {
|
|
57
|
+
async init(): Promise<boolean>
|
|
58
|
+
call<T>(method: string, data?: any): Promise<T>
|
|
59
|
+
register(method: string, handler: Function): void
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const JSBridge = {
|
|
63
|
+
scan: () => bridge.call('scan'),
|
|
64
|
+
chooseMedia: () => bridge.call('chooseMedia'),
|
|
65
|
+
// ...
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ❌ SDK 不应该做的
|
|
69
|
+
export function createVue2Plugin()
|
|
70
|
+
export function setupUniAdapter()
|
|
71
|
+
export class Monitor {}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 理念 2:不关心使用方式
|
|
75
|
+
|
|
76
|
+
**SDK 不应该强制子应用如何使用**
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// 子应用可以直接使用
|
|
80
|
+
const result = await JSBridge.scan()
|
|
81
|
+
|
|
82
|
+
// 子应用可以封装适配
|
|
83
|
+
uni.scanCode = (options) => {
|
|
84
|
+
JSBridge.scan({...}).then(...)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 子应用可以混合使用
|
|
88
|
+
// SDK 不关心!
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 理念 3:无框架绑定
|
|
92
|
+
|
|
93
|
+
**SDK 应该是纯 JavaScript,不依赖任何框架**
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
// package.json
|
|
97
|
+
{
|
|
98
|
+
"dependencies": {}, // ✅ 零依赖
|
|
99
|
+
"peerDependencies": {} // ✅ 无 peer 依赖
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// ✅ 纯 JavaScript API
|
|
105
|
+
export async function scan(options?: ScanOptions): Promise<ScanResult>
|
|
106
|
+
|
|
107
|
+
// ❌ 不应该有框架特定的代码
|
|
108
|
+
export function createVue2Plugin(options: Vue2Options)
|
|
109
|
+
export function createVue3Plugin(options: Vue3Options)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 理念 4:提供示例,而非强制
|
|
113
|
+
|
|
114
|
+
**SDK 应该提供使用示例,由子应用参考**
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
@hd-front-end/jsbridge-sdk/
|
|
118
|
+
├── dist/ # SDK 核心(打包)
|
|
119
|
+
└── examples/ # 使用示例(不打包)
|
|
120
|
+
├── direct-usage/
|
|
121
|
+
├── uni-adapter/ ← 子应用可以参考
|
|
122
|
+
└── vue-mixin/ ← 子应用可以参考
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 📊 架构对比
|
|
126
|
+
|
|
127
|
+
### 错误的架构(v2)
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
业务代码
|
|
131
|
+
↓ 调用 uni.scanCode()
|
|
132
|
+
uni API 适配层(SDK 的一部分) ← 错误!
|
|
133
|
+
↓
|
|
134
|
+
JSBridge 封装层
|
|
135
|
+
↓
|
|
136
|
+
核心通信层
|
|
137
|
+
↓
|
|
138
|
+
原生
|
|
139
|
+
|
|
140
|
+
问题:
|
|
141
|
+
1. SDK 包含适配层
|
|
142
|
+
2. 绑定 uni-app
|
|
143
|
+
3. 需要处理 Vue2/Vue3 差异
|
|
144
|
+
4. 子应用没有选择权
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 正确的架构(最终版)
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
业务代码
|
|
151
|
+
↓ 子应用决定如何使用
|
|
152
|
+
├─ 选项 1:直接调用 JSBridge.scan()
|
|
153
|
+
├─ 选项 2:uni.scanCode() (子应用封装)
|
|
154
|
+
└─ 选项 3:混合使用
|
|
155
|
+
↓
|
|
156
|
+
@hd-front-end/jsbridge-sdk (npm 包)
|
|
157
|
+
└─ 只提供 JSBridge.scan() 等原生 API
|
|
158
|
+
↓
|
|
159
|
+
原生
|
|
160
|
+
|
|
161
|
+
优势:
|
|
162
|
+
1. SDK 职责单一
|
|
163
|
+
2. 不绑定任何框架
|
|
164
|
+
3. 子应用自由选择
|
|
165
|
+
4. 易于维护
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 💡 关键认知转变
|
|
169
|
+
|
|
170
|
+
### 转变 1:SDK 不是万能的
|
|
171
|
+
|
|
172
|
+
**错误认知**:
|
|
173
|
+
> SDK 应该解决所有问题,包括适配、监控、框架兼容等
|
|
174
|
+
|
|
175
|
+
**正确认知**:
|
|
176
|
+
> SDK 只做一件事:提供稳定的原生 API。其他的由子应用决定。
|
|
177
|
+
|
|
178
|
+
### 转变 2:适配层不属于 SDK
|
|
179
|
+
|
|
180
|
+
**错误认知**:
|
|
181
|
+
> uni API 适配层应该是 SDK 的一部分,这样子应用不用改代码
|
|
182
|
+
|
|
183
|
+
**正确认知**:
|
|
184
|
+
> 适配层是子应用的选择,不应该强制。SDK 提供示例供参考。
|
|
185
|
+
|
|
186
|
+
**理由**:
|
|
187
|
+
1. 不是所有子应用都需要 uni API 适配
|
|
188
|
+
2. 不同子应用可能有不同的适配需求
|
|
189
|
+
3. 适配层的实现和维护应该由子应用控制
|
|
190
|
+
4. SDK 不应该绑定特定的 API 风格
|
|
191
|
+
|
|
192
|
+
### 转变 3:框架差异不是 SDK 的事
|
|
193
|
+
|
|
194
|
+
**错误认知**:
|
|
195
|
+
> SDK 应该处理 Vue2/Vue3 差异,提供不同的插件
|
|
196
|
+
|
|
197
|
+
**正确认知**:
|
|
198
|
+
> SDK 是纯 JavaScript,不关心框架。框架差异由子应用处理。
|
|
199
|
+
|
|
200
|
+
**理由**:
|
|
201
|
+
1. SDK 不依赖任何框架
|
|
202
|
+
2. 框架差异的处理方式因项目而异
|
|
203
|
+
3. 子应用更了解自己的技术栈
|
|
204
|
+
4. SDK 不应该为每个框架提供特定版本
|
|
205
|
+
|
|
206
|
+
### 转变 4:灵活性 > 便利性
|
|
207
|
+
|
|
208
|
+
**错误认知**:
|
|
209
|
+
> 应该让 SDK 尽可能方便,直接提供 uni API
|
|
210
|
+
|
|
211
|
+
**正确认知**:
|
|
212
|
+
> 应该让 SDK 尽可能灵活,由子应用决定如何使用
|
|
213
|
+
|
|
214
|
+
**理由**:
|
|
215
|
+
1. 便利性会牺牲灵活性
|
|
216
|
+
2. 不同项目有不同需求
|
|
217
|
+
3. 强制便利反而不便利
|
|
218
|
+
4. 灵活性才是长期价值
|
|
219
|
+
|
|
220
|
+
## 🎯 设计原则总结
|
|
221
|
+
|
|
222
|
+
### 原则 1:单一职责原则 (SRP)
|
|
223
|
+
|
|
224
|
+
**一个模块只做一件事**
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// ✅ SDK 只做原生通信
|
|
228
|
+
export const JSBridge = {
|
|
229
|
+
scan: () => bridge.call('scan'),
|
|
230
|
+
// ...
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ❌ 不做适配、监控等
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 原则 2:开闭原则 (OCP)
|
|
237
|
+
|
|
238
|
+
**对扩展开放,对修改封闭**
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// ✅ 子应用可以扩展(封装适配层)
|
|
242
|
+
uni.scanCode = (options) => {
|
|
243
|
+
JSBridge.scan({...}).then(...)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ✅ 但不需要修改 SDK
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 原则 3:依赖倒置原则 (DIP)
|
|
250
|
+
|
|
251
|
+
**依赖抽象,不依赖具体**
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
// ✅ SDK 提供抽象的 API
|
|
255
|
+
export async function scan(options?: ScanOptions): Promise<ScanResult>
|
|
256
|
+
|
|
257
|
+
// ❌ 不依赖具体的框架
|
|
258
|
+
// export function scanForVue2()
|
|
259
|
+
// export function scanForUniApp()
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 原则 4:最少知识原则 (LoD)
|
|
263
|
+
|
|
264
|
+
**只暴露必要的接口**
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// ✅ 只暴露原生 API
|
|
268
|
+
export const JSBridge = { scan, chooseMedia, ... }
|
|
269
|
+
|
|
270
|
+
// ❌ 不暴露内部实现
|
|
271
|
+
// export const bridge
|
|
272
|
+
// export class MessageQueue
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 📝 使用建议
|
|
276
|
+
|
|
277
|
+
### 给子应用开发者
|
|
278
|
+
|
|
279
|
+
**推荐做法**:
|
|
280
|
+
|
|
281
|
+
1. **直接使用(最简单)**
|
|
282
|
+
```typescript
|
|
283
|
+
const result = await JSBridge.scan()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
2. **封装适配(如需要)**
|
|
287
|
+
```typescript
|
|
288
|
+
// 在子应用中封装
|
|
289
|
+
uni.scanCode = (options) => {
|
|
290
|
+
JSBridge.scan({...}).then(...)
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
3. **混合使用(最灵活)**
|
|
295
|
+
```typescript
|
|
296
|
+
// 新代码直接用 SDK
|
|
297
|
+
await JSBridge.scan()
|
|
298
|
+
|
|
299
|
+
// 旧代码继续用 uni API(如果有适配)
|
|
300
|
+
uni.scanCode({ success: ... })
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**不推荐做法**:
|
|
304
|
+
|
|
305
|
+
1. ❌ 期望 SDK 提供 uni API 适配
|
|
306
|
+
2. ❌ 期望 SDK 处理框架差异
|
|
307
|
+
3. ❌ 期望 SDK 包含业务逻辑
|
|
308
|
+
|
|
309
|
+
### 给 SDK 维护者
|
|
310
|
+
|
|
311
|
+
**应该做的**:
|
|
312
|
+
|
|
313
|
+
1. ✅ 保持 API 稳定
|
|
314
|
+
2. ✅ 完善类型定义
|
|
315
|
+
3. ✅ 提供使用示例
|
|
316
|
+
4. ✅ 文档清晰完整
|
|
317
|
+
|
|
318
|
+
**不应该做的**:
|
|
319
|
+
|
|
320
|
+
1. ❌ 添加框架特定代码
|
|
321
|
+
2. ❌ 添加适配层
|
|
322
|
+
3. ❌ 添加业务逻辑
|
|
323
|
+
4. ❌ 添加复杂功能
|
|
324
|
+
|
|
325
|
+
## 🔍 对比示例
|
|
326
|
+
|
|
327
|
+
### 示例:扫码功能
|
|
328
|
+
|
|
329
|
+
#### 错误的设计(v2)
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// SDK 包含适配层
|
|
333
|
+
export function setupUniAdapter() {
|
|
334
|
+
uni.scanCode = (options) => {
|
|
335
|
+
JSBridge.scan({...}).then(...)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// 子应用被强制使用 uni API
|
|
340
|
+
uni.scanCode({ success: ... })
|
|
341
|
+
|
|
342
|
+
// 问题:
|
|
343
|
+
// 1. SDK 绑定 uni-app
|
|
344
|
+
// 2. 子应用没有选择
|
|
345
|
+
// 3. 不需要 uni API 的项目也要引入
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
#### 正确的设计(最终版)
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
// SDK 只提供原生 API
|
|
352
|
+
export const JSBridge = {
|
|
353
|
+
scan: (options?: ScanOptions) => bridge.call('scan', options)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// 子应用选择 1:直接使用
|
|
357
|
+
const result = await JSBridge.scan()
|
|
358
|
+
|
|
359
|
+
// 子应用选择 2:自己封装适配(可选)
|
|
360
|
+
// 在子应用项目中:
|
|
361
|
+
uni.scanCode = (options) => {
|
|
362
|
+
JSBridge.scan({...}).then(...)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// 优势:
|
|
366
|
+
// 1. SDK 不绑定框架
|
|
367
|
+
// 2. 子应用自由选择
|
|
368
|
+
// 3. 灵活性高
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## 📊 价值对比
|
|
372
|
+
|
|
373
|
+
| 维度 | 包含适配层(错误) | 纯 API 封装(正确) |
|
|
374
|
+
|------|------------------|-------------------|
|
|
375
|
+
| **SDK 职责** | 通信 + 适配 | 只通信 |
|
|
376
|
+
| **代码量** | 880 行 | 600 行 |
|
|
377
|
+
| **体积** | 20KB | 12KB |
|
|
378
|
+
| **依赖** | 可能依赖框架 | 零依赖 |
|
|
379
|
+
| **灵活性** | 低(强制方式) | 高(自由选择) |
|
|
380
|
+
| **维护成本** | 高(多关注点) | 低(单一关注点) |
|
|
381
|
+
| **学习成本** | 高(复杂) | 低(简单) |
|
|
382
|
+
| **适用范围** | 限 uni-app | 所有项目 |
|
|
383
|
+
|
|
384
|
+
## 🎓 经验教训
|
|
385
|
+
|
|
386
|
+
### 教训 1:避免过度设计
|
|
387
|
+
|
|
388
|
+
**问题**:v1 版本支持 Vue2/Vue3/React,实际只需要 uni-app
|
|
389
|
+
|
|
390
|
+
**教训**:先满足实际需求,不要过度抽象
|
|
391
|
+
|
|
392
|
+
### 教训 2:理解职责边界
|
|
393
|
+
|
|
394
|
+
**问题**:v2 版本把适配层当成 SDK 一部分
|
|
395
|
+
|
|
396
|
+
**教训**:清楚区分 SDK 和子应用的职责
|
|
397
|
+
|
|
398
|
+
### 教训 3:灵活性 > 便利性
|
|
399
|
+
|
|
400
|
+
**问题**:想让 SDK"方便",强制提供 uni API
|
|
401
|
+
|
|
402
|
+
**教训**:灵活性才是长期价值,便利性可以由子应用实现
|
|
403
|
+
|
|
404
|
+
### 教训 4:听取用户反馈
|
|
405
|
+
|
|
406
|
+
**问题**:闭门造车,没理解实际需求
|
|
407
|
+
|
|
408
|
+
**教训**:用户提出的问题往往指出了核心缺陷
|
|
409
|
+
|
|
410
|
+
## ✅ 最终结论
|
|
411
|
+
|
|
412
|
+
### SDK 应该是什么
|
|
413
|
+
|
|
414
|
+
**纯粹的原生 API 封装库**
|
|
415
|
+
- 600 行代码
|
|
416
|
+
- 12KB 体积
|
|
417
|
+
- 零依赖
|
|
418
|
+
- 完整类型定义
|
|
419
|
+
- 简单直接
|
|
420
|
+
|
|
421
|
+
### SDK 不应该是什么
|
|
422
|
+
|
|
423
|
+
- ❌ 不是 uni API 适配框架
|
|
424
|
+
- ❌ 不是 Vue/React 组件库
|
|
425
|
+
- ❌ 不是监控系统
|
|
426
|
+
- ❌ 不是业务逻辑框架
|
|
427
|
+
|
|
428
|
+
### 核心价值
|
|
429
|
+
|
|
430
|
+
1. **职责单一** - 只做原生通信
|
|
431
|
+
2. **灵活使用** - 子应用自由选择
|
|
432
|
+
3. **易于维护** - 代码简洁清晰
|
|
433
|
+
4. **长期价值** - 不过时、不臃肿
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
**回归本质,聚焦核心** - 这就是正确的设计理念! 🎯
|
|
438
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hd-front-end/jsbridge-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "HD JSBridge SDK - 统一的原生能力封装",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"README.md"
|
|
11
|
+
"README.md",
|
|
12
|
+
"docs"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"dev": "rollup -c -w",
|