XuqmGroup-RNSDK/docs/配置文件规范.md
XuqmGroup 507ce3d2ee feat(update): release-set 事务制品与原生层职责拆分
- 插件包改为 .xuqm.zip 事务制品,manifest/bundle/资源/SHA-256 统一校验
- 原生层拆分为桥接编排、插件包暂存、底层存储三个单一职责类
- 状态查询改为纯读取,不再误触发安装;新增 NATIVE_BASELINE_INCOMPATIBLE 拒绝
- SemVer 解析拆分为独立原生类并补原生测试
- XWebView 收口唯一内核,错误态统一中文层与重试
- common 增加请求头/运行时契约收口与 http 测试
2026-07-20 19:31:43 +08:00

3.9 KiB

Xuqm RN 配置文件规范

Xuqm RN 扩展 SDK 只支持一种自动初始化方案:宿主保存一份平台签发的 .xuqmconfig 原始加密文件,并用 withXuqmConfig() 包装 Metro。不得创建 TypeScript 配置副本、手动 alias 或在业务代码硬编码 appKey。

common-only 项目

只使用 @xuqm/rn-common 的文件、时间、加密、设备、UI 或自定义网络能力时:

  • 不放 .xuqmconfig
  • 不使用 withXuqmConfig()
  • 不调用 XuqmSDK.initialize()
  • 不调用 XuqmSDK.login()

common-only 模式保持零初始化、零登录。

扩展 SDK 项目

安装 update、bugcollect、xwebview 等扩展后,将平台签发的原始文件放到:

src/assets/config/config.xuqmconfig

文件名也可以是其他 *.xuqmconfig。扫描优先级为:

  1. config.xuqmconfig
  2. config.xuqm
  3. 目录中的第一个 *.xuqmconfig

Metro 配置只包装一次:

const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
const { withXuqmConfig } = require('@xuqm/rn-common/metro')

const baseConfig = mergeConfig(getDefaultConfig(__dirname), {
  // 宿主自己的 Metro 配置
})

module.exports = withXuqmConfig(baseConfig)

自动初始化时序

Metro 读取唯一 .xuqmconfig
  → 生成构建期传输模块
  → 注册 @xuqm/rn-common/internal 为 pre-main module
  → 解密配置
  → 使用 appKey 请求远程 SDK 配置
  → 初始化唯一 HTTP/扩展上下文
  → 执行业务入口

pre-main 机制保证初始化不受 Metro inlineRequires 和业务模块加载顺序影响。解密开始后,所有 awaitInitialization() 调用都等待同一个 Promise。

原生配置同步

withXuqmConfig() 会把同一份源文件幂等同步到:

android/app/src/main/assets/config/config.xuqmconfig
ios/<App>/config/config.xuqmconfig

这些位置是构建目标,不是第二配置源。宿主只维护 src/assets/config 下的原文件。

加密文件

文件格式:

XUQM-CONFIG-V1.{salt}.{iv}.{ciphertextAndTag}
  • PBKDF2-HMAC-SHA256
  • AES-256-GCM
  • 12 字节 IV
  • 16 字节认证标签

解密后的必要字段为 appKey,可选字段包括 serverUrlbaseUrlsigningKeyserverUrl 优先、baseUrl 次之,二者都表示 Xuqm 租户平台地址并在运行时归一为 platformUrl;它们不是 App 业务接口地址。明文结构由平台负责签发,业务仓库不得自行构造。

远程配置响应中的 apiUrl 是业务扩展服务地址,与配置文件中的平台地址职责不同:

配置文件 serverUrl/baseUrl
  → platformUrl
  → /api/sdk/config、整包更新、插件 release set 等 Xuqm 平台接口

平台返回 apiUrl
  → 业务扩展服务
  → 只有明确依赖该服务的扩展能力使用

禁止把远程 apiUrl 写回公共 HTTP 基础地址,否则会把版本检查错误地发送到 App 自身业务服务。

登录

初始化与业务登录是两个动作。App 登录完成后只同步一次公共会话:

import { XuqmSDK } from '@xuqm/rn-common'

await XuqmSDK.awaitInitialization()
await XuqmSDK.login({
  userId: 'user-id',
  accessToken: 'access-token',
  name: '姓名',
  phone: '手机号',
})

退出时只调用:

await XuqmSDK.logout()

扩展包不得各自初始化或登录,业务代码不得导入 @xuqm/rn-common/internal

失败规则

  • 扩展项目缺少配置:awaitInitialization() 明确报错。
  • 解密失败或远程配置失败:初始化 Promise 拒绝并保留原始错误。
  • 不自动切换到硬编码配置,不静默创建默认租户,不提供多级兼容回退。
  • common-only 项目没有配置时不会执行初始化,也不会报错。

安全约束

  • 不打印密文或解密后的配置。
  • 不提交明文 appKey、signingKey 或租户密钥。
  • 不在多个目录手工维护配置副本。
  • .xuqmconfig 变更必须通过平台重新签发。