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) {
|
function withXuqmConfig(metroConfig) {
|
||||||
const projectRoot = metroConfig.projectRoot ?? process.cwd();
|
const projectRoot = metroConfig.projectRoot ?? process.cwd();
|
||||||
const configFile = findConfigFile(projectRoot);
|
const configFile = findConfigFile(projectRoot);
|
||||||
@ -70,6 +122,9 @@ function withXuqmConfig(metroConfig) {
|
|||||||
// 读取加密配置内容
|
// 读取加密配置内容
|
||||||
const encryptedContent = fs.readFileSync(configFile, 'utf-8').trim();
|
const encryptedContent = fs.readFileSync(configFile, 'utf-8').trim();
|
||||||
|
|
||||||
|
// 单点放置:自动同步到原生 Android/iOS(缺失或不一致才复制)
|
||||||
|
syncNativeConfig(projectRoot, encryptedContent);
|
||||||
|
|
||||||
// 生成临时 TS 文件作为虚拟模块
|
// 生成临时 TS 文件作为虚拟模块
|
||||||
const tmpDir = path.join(os.tmpdir(), 'xuqm-sdk-config');
|
const tmpDir = path.join(os.tmpdir(), 'xuqm-sdk-config');
|
||||||
fs.mkdirSync(tmpDir, { recursive: true });
|
fs.mkdirSync(tmpDir, { recursive: true });
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户