feat(common/metro): .xuqmconfig 单点放置——自动同步到原生 Android/iOS
宿主只需在 RN 侧放置一份 .xuqmconfig;构建/运行时 withXuqmConfig 自动比对并 复制到 android assets/config(供 XuqmMergedProvider 自动初始化)及 iOS 资源目录, 缺失或内容不一致才写入(幂等)。免去 RN/Android/iOS 三处分别放置。 Co-Authored-By: Claude <noreply@anthropic.com>
这个提交包含在:
父节点
4d5adf447a
当前提交
d51d3c934d
@ -58,6 +58,58 @@ function applyBugCollect(metroConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 写入目标文件(仅在缺失或内容不一致时),返回是否发生写入。 */
|
||||
function syncFile(content, destPath, label) {
|
||||
try {
|
||||
if (fs.existsSync(destPath) && fs.readFileSync(destPath, 'utf-8').trim() === content) {
|
||||
return false;
|
||||
}
|
||||
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
||||
fs.writeFileSync(destPath, content, 'utf-8');
|
||||
console.log(`[XuqmConfig] 已同步 .xuqmconfig → ${label}`);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn(`[XuqmConfig] 同步 .xuqmconfig 到 ${label} 失败:${e.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单点放置:宿主只在 RN 侧放置一份 .xuqmconfig,构建/运行时自动同步到
|
||||
* 原生位置(Android assets/config,供 XuqmMergedProvider 自动初始化;iOS 资源目录)。
|
||||
* 缺失或内容不一致才复制,幂等。
|
||||
*/
|
||||
function syncNativeConfig(projectRoot, content) {
|
||||
const fileName = 'config.xuqmconfig';
|
||||
|
||||
// Android:原生 ContentProvider 扫描 assets/config 下的 .xuqmconfig
|
||||
if (fs.existsSync(path.resolve(projectRoot, 'android'))) {
|
||||
syncFile(
|
||||
content,
|
||||
path.resolve(projectRoot, 'android/app/src/main/assets/config', fileName),
|
||||
'android assets/config',
|
||||
);
|
||||
}
|
||||
|
||||
// iOS:复制到 app 资源目录(需在 Xcode「Copy Bundle Resources」中引用一次)
|
||||
const iosDir = path.resolve(projectRoot, 'ios');
|
||||
if (fs.existsSync(iosDir)) {
|
||||
try {
|
||||
const appDir = fs
|
||||
.readdirSync(iosDir, { withFileTypes: true })
|
||||
.filter(
|
||||
(d) => d.isDirectory() && fs.existsSync(path.join(iosDir, d.name, 'Info.plist')),
|
||||
)
|
||||
.map((d) => d.name)[0];
|
||||
if (appDir) {
|
||||
syncFile(content, path.join(iosDir, appDir, 'config', fileName), `ios ${appDir}/config`);
|
||||
}
|
||||
} catch {
|
||||
// 忽略 iOS 同步异常,不阻断打包
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withXuqmConfig(metroConfig) {
|
||||
const projectRoot = metroConfig.projectRoot ?? process.cwd();
|
||||
const configFile = findConfigFile(projectRoot);
|
||||
@ -70,6 +122,9 @@ function withXuqmConfig(metroConfig) {
|
||||
// 读取加密配置内容
|
||||
const encryptedContent = fs.readFileSync(configFile, 'utf-8').trim();
|
||||
|
||||
// 单点放置:自动同步到原生 Android/iOS(缺失或不一致才复制)
|
||||
syncNativeConfig(projectRoot, encryptedContent);
|
||||
|
||||
// 生成临时 TS 文件作为虚拟模块
|
||||
const tmpDir = path.join(os.tmpdir(), 'xuqm-sdk-config');
|
||||
fs.mkdirSync(tmpDir, { recursive: true });
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户