docs: 更新 README + 配置文件规范 + 架构总览(BugCollect/withXuqmConfig)
Co-Authored-By: Claude <noreply@anthropic.com>
这个提交包含在:
父节点
4f5739da1f
当前提交
a9f320db63
60
README.md
60
README.md
@ -1,6 +1,6 @@
|
||||
# XuqmGroup React Native SDK
|
||||
|
||||
Modular React Native SDK providing IM, Push, App/Plugin Update, WebView, and License management for XuqmGroup platform applications.
|
||||
Modular React Native SDK providing IM, Push, App/Plugin Update, WebView, BugCollect, and License management for XuqmGroup platform applications.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@ -38,11 +38,12 @@ XuqmGroup-RNSDK/ # @xuqm/rn-sdk (meta-package, private)
|
||||
│ ├── index.ts # Re-exports all sub-packages
|
||||
│ └── sdk.ts # Unified login / logout
|
||||
├── packages/
|
||||
│ ├── common/ @xuqm/rn-common # Init, network, device, token, HTTP, auto-init
|
||||
│ ├── common/ @xuqm/rn-common # Init, network, device, token, HTTP, auto-init, Metro plugins
|
||||
│ ├── im/ @xuqm/rn-im # IM messaging (WebSocket/STOMP + WatermelonDB)
|
||||
│ ├── push/ @xuqm/rn-push # Multi-vendor push registration
|
||||
│ ├── update/ @xuqm/rn-update # App update check + RN plugin hot-update
|
||||
│ └── xwebview/ @xuqm/rn-xwebview # Enhanced WebView with JSBridge
|
||||
│ ├── xwebview/ @xuqm/rn-xwebview # Enhanced WebView with JSBridge
|
||||
│ └── bugcollect/ @xuqm/rn-bugcollect # Error capture, crash reporting, funnel analytics
|
||||
```
|
||||
|
||||
All packages are at version **0.2.2**.
|
||||
@ -73,7 +74,7 @@ yarn add @react-native-async-storage/async-storage
|
||||
**Option B -- Individual packages:**
|
||||
|
||||
```bash
|
||||
yarn add @xuqm/rn-common @xuqm/rn-update @xuqm/rn-xwebview
|
||||
yarn add @xuqm/rn-common @xuqm/rn-update @xuqm/rn-xwebview @xuqm/rn-bugcollect
|
||||
yarn add @react-native-async-storage/async-storage
|
||||
```
|
||||
|
||||
@ -88,6 +89,9 @@ yarn add react-native-webview react-native-blob-util react-native-svg
|
||||
|
||||
# Config file decryption (auto-init)
|
||||
yarn add react-native-quick-crypto
|
||||
|
||||
# BugCollect module (if using @xuqm/rn-bugcollect)
|
||||
yarn add @xuqm/rn-bugcollect
|
||||
```
|
||||
|
||||
---
|
||||
@ -96,21 +100,19 @@ yarn add react-native-quick-crypto
|
||||
|
||||
### Zero-config initialization (recommended)
|
||||
|
||||
Place an encrypted `.xuqmconfig` file (XUQM-CONFIG-V1 format) in your project, then add a Metro alias so the SDK can auto-discover it:
|
||||
Place the encrypted `.xuqmconfig` file (XUQM-CONFIG-V1 format) downloaded from the tenant platform into `src/assets/config/`, then wrap your Metro config with `withXuqmConfig`:
|
||||
|
||||
```js
|
||||
// metro.config.js
|
||||
const { getDefaultConfig } = require('metro-config');
|
||||
module.exports = (async () => {
|
||||
const config = await getDefaultConfig(__dirname);
|
||||
config.resolver.extraNodeModules = {
|
||||
'@xuqm/autoinit-config': './path/to/your.xuqmconfig',
|
||||
};
|
||||
return config;
|
||||
})();
|
||||
const { getDefaultConfig } = require('@react-native/metro-config');
|
||||
const { withXuqmConfig } = require('@xuqm/rn-common/metro');
|
||||
const baseConfig = getDefaultConfig(__dirname);
|
||||
module.exports = withXuqmConfig(baseConfig);
|
||||
```
|
||||
|
||||
That is it. When `@xuqm/rn-common` is imported, it silently calls `XuqmSDK.initWithConfigFile()` using the encrypted file. No explicit init code needed.
|
||||
That is it. `withXuqmConfig` automatically discovers the config file from `src/assets/config/` (or `src/assets/xuqm/`) and wires up the virtual module. When `@xuqm/rn-common` is imported, it silently calls `XuqmSDK.initWithConfigFile()` using the encrypted file. No explicit init code needed.
|
||||
|
||||
**Compatible fallback:** You can also manually configure a Babel/Metro alias for `@xuqm/autoinit-config` pointing to a `.ts` wrapper file. See `docs/配置文件规范.md` for details.
|
||||
|
||||
### Manual initialization
|
||||
|
||||
@ -260,6 +262,34 @@ Enhanced WebView with JSBridge for bidirectional communication between RN and we
|
||||
|
||||
---
|
||||
|
||||
### @xuqm/rn-bugcollect
|
||||
|
||||
Error capture, crash reporting, and funnel analytics. Provides global JS error capture, custom event tracking, and batched async upload to the BugCollect service.
|
||||
|
||||
| Export | Description |
|
||||
|--------|-------------|
|
||||
| `BugCollect.setLogLevel(level)` | Set minimum log level (`debug` / `info` / `warn` / `error`) |
|
||||
| `BugCollect.setEnvironment(env)` | Set environment tag (`development` / `staging` / `production`) |
|
||||
| `BugCollect.startCapture()` | Enable global JS error and unhandled Promise rejection capture |
|
||||
| `BugCollect.event(name, properties?)` | Record a custom analytics event |
|
||||
| `BugCollect.captureError(error, metadata?)` | Report a JS exception |
|
||||
| `BugCollect.warn(message, metadata?)` | Log a warning |
|
||||
| `BugCollect.info(message, metadata?)` | Log an info event |
|
||||
| `BugCollect.defineFunnel(id, steps)` | Define a conversion funnel |
|
||||
| `BugCollect.getFunnelProgress(funnelId)` | Get client-side funnel progress |
|
||||
| `BugCollect.flush()` | Immediately flush all pending events |
|
||||
|
||||
**Metro plugin:** `@xuqm/rn-bugcollect/metro` exports `withBugCollect` for automatic SourceMap upload on Release builds.
|
||||
|
||||
```js
|
||||
const { withBugCollect } = require('@xuqm/rn-bugcollect/metro');
|
||||
module.exports = withBugCollect(baseConfig);
|
||||
```
|
||||
|
||||
**Config:** `bugCollectApiUrl` and `bugCollectEnabled` are automatically obtained from the platform config (`/api/sdk/config`) after `@xuqm/rn-common` init. No app-level configuration needed.
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
@ -288,7 +318,7 @@ cd packages/common
|
||||
npm publish
|
||||
|
||||
# Publish all packages (from each package directory)
|
||||
for pkg in common im push update xwebview; do
|
||||
for pkg in common im push update xwebview bugcollect; do
|
||||
cd packages/$pkg && npm publish && cd ../..
|
||||
done
|
||||
```
|
||||
|
||||
23
docs/架构总览.md
23
docs/架构总览.md
@ -21,7 +21,7 @@
|
||||
├── @xuqm/rn-im → IM 会话 / 消息(peerDep: rn-common)
|
||||
├── @xuqm/rn-xwebview → WebView UI 组件(peerDep: rn-common)
|
||||
├── @xuqm/rn-license → 证书授权(peerDep: rn-common)
|
||||
└── @xuqm/rn-log → 日志 / 追踪(peerDep: rn-common)
|
||||
└── @xuqm/rn-bugcollect → 错误采集 / Crash 捕获 / 漏斗分析(peerDep: rn-common)
|
||||
```
|
||||
|
||||
## 依赖关系
|
||||
@ -34,7 +34,7 @@ rn-common (核心,无 SDK 内部依赖)
|
||||
├── rn-im (peerDep rn-common + watermelondb)
|
||||
├── rn-xwebview (peerDep rn-common + webview + navigation)
|
||||
├── rn-license (peerDep rn-common + quick-crypto)
|
||||
└── rn-log (peerDep rn-common)
|
||||
└── rn-bugcollect(peerDep rn-common)
|
||||
```
|
||||
|
||||
## 用户状态分发机制
|
||||
@ -56,18 +56,21 @@ XuqmSDK.setUserInfo(null)
|
||||
|
||||
## 初始化流程
|
||||
|
||||
### 方式 A(自动)
|
||||
### 方式 A(自动,推荐)
|
||||
|
||||
```
|
||||
Metro alias → @xuqm/autoinit-config → encrypted .xuqmconfig
|
||||
↓ import 时触发
|
||||
autoInit.ts → require('@xuqm/autoinit-config')
|
||||
withXuqmConfig(metroConfig) 自动发现 src/assets/config/*.xuqmconfig
|
||||
↓ 生成虚拟模块 @xuqm/autoinit-config
|
||||
import '@xuqm/rn-common' 时触发
|
||||
↓ autoInit.ts → require('@xuqm/autoinit-config')
|
||||
↓ 解密(PBKDF2 + AES-256-GCM)
|
||||
initWithConfigFile() → initialize({ appKey, platformUrl })
|
||||
↓ HTTP GET
|
||||
/api/sdk/config → 返回 { apiUrl, imWsUrl, fileServiceUrl, ... }
|
||||
/api/sdk/config → 返回 { apiUrl, imWsUrl, fileServiceUrl, bugCollectApiUrl, ... }
|
||||
```
|
||||
|
||||
兼容方式:手动配置 Babel/Metro alias `@xuqm/autoinit-config` → `.ts` 包装文件。
|
||||
|
||||
### 方式 B(手动)
|
||||
|
||||
```
|
||||
@ -83,11 +86,11 @@ App 代码调用 XuqmSDK.initialize({ appKey })
|
||||
```
|
||||
App 代码
|
||||
↓ 调用 API
|
||||
子 SDK(update/push/im/license/log)
|
||||
子 SDK(update/push/im/license/bugcollect)
|
||||
↓ 使用 apiRequest()
|
||||
rn-common http.ts
|
||||
↓ 附加 Bearer Token + 处理响应
|
||||
平台服务(tenant-service / im-service / push-service / update-service / log-service)
|
||||
平台服务(tenant-service / im-service / push-service / update-service / bugcollect-service)
|
||||
```
|
||||
|
||||
## 包发布
|
||||
@ -99,7 +102,7 @@ rn-common http.ts
|
||||
cd packages/common && npm publish
|
||||
|
||||
# 发布所有包
|
||||
for pkg in common update push im xwebview license log; do
|
||||
for pkg in common update push im xwebview license bugcollect; do
|
||||
cd packages/$pkg && npm publish && cd ../..
|
||||
done
|
||||
```
|
||||
|
||||
@ -75,7 +75,26 @@ XUQM-CONFIG-V1.{base64urlSalt}.{base64urlIV}.{base64urlCiphertext}
|
||||
|
||||
### React Native(Metro bundler)
|
||||
|
||||
由于 Metro 只能 bundle JS/TS 模块,配置文件使用 `.ts` 扩展名。
|
||||
#### 推荐方式:withXuqmConfig Metro 插件
|
||||
|
||||
将平台下载的 `.xuqmconfig` 加密文件直接放入 `src/assets/config/`(推荐)或 `src/assets/xuqm/`,然后用 `withXuqmConfig` 包裹 Metro 配置:
|
||||
|
||||
**文件位置**:`src/assets/config/config.xuqmconfig`(原始加密文件,无需改名或创建 `.ts` 包装)
|
||||
|
||||
**Metro 配置**(`metro.config.js`):
|
||||
|
||||
```javascript
|
||||
const { getDefaultConfig } = require('@react-native/metro-config');
|
||||
const { withXuqmConfig } = require('@xuqm/rn-common/metro');
|
||||
const baseConfig = getDefaultConfig(__dirname);
|
||||
module.exports = withXuqmConfig(baseConfig);
|
||||
```
|
||||
|
||||
`withXuqmConfig` 会自动扫描 `src/assets/config/` 和 `src/assets/xuqm/` 目录,优先查找 `config.xuqmconfig` 或 `config.xuqm`,否则取第一个 `.xuqmconfig` 文件。找到后生成虚拟模块并注入 Metro 解析链,SDK import 时自动读取并初始化。
|
||||
|
||||
#### 兼容方式:手动 alias
|
||||
|
||||
如果无法使用 Metro 插件,也可以手动配置 alias。由于 Metro 只能 bundle JS/TS 模块,配置文件使用 `.ts` 扩展名。
|
||||
|
||||
**文件位置**:`src/assets/xuqm/config.xuqmconfig.ts`
|
||||
|
||||
|
||||
@ -84,6 +84,26 @@ console.log(progress?.completedSteps) // ['cart_view', 'checkout_start', 'paymen
|
||||
3. **Fingerprint**:为每个错误生成指纹(基于 message + stack),用于服务端去重聚合
|
||||
4. **FunnelTracker**:客户端维护漏斗进度,服务端跨 session 聚合
|
||||
|
||||
## Metro 插件(SourceMap 自动上传)
|
||||
|
||||
`@xuqm/rn-bugcollect/metro` 导出 `withBugCollect`,包裹 Metro 配置后,打 Release 包时自动上传 SourceMap:
|
||||
|
||||
```js
|
||||
// metro.config.js
|
||||
const { getDefaultConfig } = require('@react-native/metro-config');
|
||||
const { withXuqmConfig } = require('@xuqm/rn-common/metro');
|
||||
const { withBugCollect } = require('@xuqm/rn-bugcollect/metro');
|
||||
const baseConfig = getDefaultConfig(__dirname);
|
||||
module.exports = withBugCollect(withXuqmConfig(baseConfig));
|
||||
```
|
||||
|
||||
## 导出清单
|
||||
|
||||
| 导出 | 来源 | 说明 |
|
||||
|------|------|------|
|
||||
| `BugCollect` | `@xuqm/rn-bugcollect` | 主对象(setLogLevel / setEnvironment / startCapture / event / captureError / warn / info / defineFunnel / getFunnelProgress / flush) |
|
||||
| `withBugCollect` | `@xuqm/rn-bugcollect/metro` | Metro 插件,自动上传 SourceMap |
|
||||
|
||||
## 配置
|
||||
|
||||
`bugCollectApiUrl` 和 `bugCollectEnabled` 由 `@xuqm/rn-common` 在 init 后从 `/api/sdk/config` 自动获取,无需 App 传入。
|
||||
|
||||
@ -14,17 +14,20 @@ Peer dependencies:`react >= 18`,`react-native >= 0.76`,`axios >= 1.0.0`
|
||||
|
||||
### 方式 A — 配置文件自动初始化(推荐)
|
||||
|
||||
在宿主项目中配置 Babel alias `@xuqm/autoinit-config` → 加密配置文件:
|
||||
将平台下载的 `.xuqmconfig` 文件放入 `src/assets/config/`,然后用 `withXuqmConfig` Metro 插件自动发现:
|
||||
|
||||
```js
|
||||
// metro.config.js
|
||||
config.resolver.extraNodeModules = {
|
||||
'@xuqm/autoinit-config': './path/to/your.xuqmconfig',
|
||||
};
|
||||
const { getDefaultConfig } = require('@react-native/metro-config');
|
||||
const { withXuqmConfig } = require('@xuqm/rn-common/metro');
|
||||
const baseConfig = getDefaultConfig(__dirname);
|
||||
module.exports = withXuqmConfig(baseConfig);
|
||||
```
|
||||
|
||||
SDK 在 import 时自动调用 `initWithConfigFile()`,App 无需任何 init 代码。
|
||||
|
||||
**兼容方式**:也可手动配置 Babel alias `@xuqm/autoinit-config` → `.ts` 包装文件。
|
||||
|
||||
### 方式 B — 手动初始化
|
||||
|
||||
```ts
|
||||
@ -101,6 +104,12 @@ await XuqmSDK.awaitInitialization() // 等待配置拉取
|
||||
| `showConfirm(title, msg)` | 显示确认对话框 |
|
||||
| `ScaledImage` | 等比缩放图片组件 |
|
||||
|
||||
### Metro 插件
|
||||
|
||||
| 导出 | 来源 | 说明 |
|
||||
|------|------|------|
|
||||
| `withXuqmConfig` | `@xuqm/rn-common/metro` | 自动发现 `.xuqmconfig` 配置文件并注入虚拟模块,推荐方式 |
|
||||
|
||||
### 常量
|
||||
|
||||
| 常量 | 说明 |
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户