# 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 等扩展后,将平台签发的原始文件放到: ```text src/assets/config/config.xuqmconfig ``` 文件名也可以是其他 `*.xuqmconfig`。扫描优先级为: 1. `config.xuqmconfig` 2. `config.xuqm` 3. 目录中的第一个 `*.xuqmconfig` Metro 配置只包装一次: ```js 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) ``` ## 自动初始化时序 ```text Metro 读取唯一 .xuqmconfig → 生成构建期传输模块 → 注册 @xuqm/rn-common/internal 为 pre-main module → 解密配置 → 使用 appKey 请求远程 SDK 配置 → 初始化唯一 HTTP/扩展上下文 → 执行业务入口 ``` pre-main 机制保证初始化不受 Metro `inlineRequires` 和业务模块加载顺序影响。解密开始后,所有 `awaitInitialization()` 调用都等待同一个 Promise。 ## 原生配置同步 `withXuqmConfig()` 会把同一份源文件幂等同步到: ```text android/app/src/main/assets/config/config.xuqmconfig ios//config/config.xuqmconfig ``` 这些位置是构建目标,不是第二配置源。宿主只维护 `src/assets/config` 下的原文件。 ## 加密文件 文件格式: ```text XUQM-CONFIG-V1.{salt}.{iv}.{ciphertextAndTag} ``` - PBKDF2-HMAC-SHA256 - AES-256-GCM - 12 字节 IV - 16 字节认证标签 解密后的必要字段为 `appKey`,可选字段包括 `serverUrl`、`baseUrl` 和 `signingKey`。`serverUrl` 优先、`baseUrl` 次之,二者都表示 Xuqm 租户平台地址并在运行时归一为 `platformUrl`;它们不是 App 业务接口地址。明文结构由平台负责签发,业务仓库不得自行构造。 远程配置响应中的 `apiUrl` 是业务扩展服务地址,与配置文件中的平台地址职责不同: ```text 配置文件 serverUrl/baseUrl → platformUrl → /api/sdk/config、整包更新、插件 release set 等 Xuqm 平台接口 平台返回 apiUrl → 业务扩展服务 → 只有明确依赖该服务的扩展能力使用 ``` 禁止把远程 `apiUrl` 写回公共 HTTP 基础地址,否则会把版本检查错误地发送到 App 自身业务服务。 ## 登录 初始化与业务登录是两个动作。App 登录完成后只同步一次公共会话: ```ts import { XuqmSDK } from '@xuqm/rn-common' await XuqmSDK.awaitInitialization() await XuqmSDK.login({ userId: 'user-id', accessToken: 'access-token', name: '姓名', phone: '手机号', }) ``` 退出时只调用: ```ts await XuqmSDK.logout() ``` 扩展包不得各自初始化或登录,业务代码不得导入 `@xuqm/rn-common/internal`。 ## 失败规则 - 扩展项目缺少配置:`awaitInitialization()` 明确报错。 - 解密失败或远程配置失败:初始化 Promise 拒绝并保留原始错误。 - 不自动切换到硬编码配置,不静默创建默认租户,不提供多级兼容回退。 - common-only 项目没有配置时不会执行初始化,也不会报错。 ## 安全约束 - 不打印密文或解密后的配置。 - 不提交明文 appKey、signingKey 或租户密钥。 - 不在多个目录手工维护配置副本。 - `.xuqmconfig` 变更必须通过平台重新签发。