/** * initMultiBundle - 多 Bundle 统一初始化入口 * 封装所有初始化逻辑,业务代码只需调用一次即可完成所有初始化 */ import { ModuleRegistry, BundleManifest } from './ModuleRegistry'; import { preloadModule } from './preloadModule'; import { mergeConfig, setGlobalConfig, MultiBundleConfig } from './config'; import { LocalBundleManager } from './LocalBundleManager'; import { HMRClient } from './HMRClient'; /** * 初始化结果 */ export interface InitResult { success: boolean; error?: Error; manifest?: BundleManifest; } // 初始化状态标记 let isInitialized = false; let initPromise: Promise | null = null; /** * 从 manifestProvider 获取 manifest */ async function getManifestFromProvider( provider: MultiBundleConfig['manifestProvider'] ): Promise { if (!provider) { // 如果没有提供 provider,使用默认的 LocalBundleManager return await LocalBundleManager.getCurrentBundleManifest(); } if (typeof provider === 'string') { // URL 模式:从 HTTP 服务器获取 try { const response = await fetch(provider); if (response.ok) { return await response.json(); } throw new Error(`Failed to fetch manifest from ${provider}: ${response.statusText}`); } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); console.warn(`[initMultiBundle] Failed to fetch manifest from URL: ${err.message}`); // 降级到默认方式 return await LocalBundleManager.getCurrentBundleManifest(); } } else { // 函数模式:调用自定义函数 return await provider(); } } /** * 初始化多 Bundle 系统 * * @param config 配置对象 * @param forceReinit 是否强制重新初始化(默认 false,已初始化时直接返回成功结果) * @returns 初始化结果 * * @example * ```typescript * const result = await initMultiBundle({ * modulePaths: ['src/modules/**'], * sharedDependencies: ['src/multi-bundle/**', 'src/navigation/**'], * preloadModules: ['settings'], * }); * ``` */ export async function initMultiBundle( config: MultiBundleConfig = {}, forceReinit: boolean = false ): Promise { // 如果已经初始化且不强制重新初始化,直接返回成功 if (isInitialized && !forceReinit) { return { success: true, manifest: undefined, // 不返回 manifest,因为已经初始化过了 }; } // 如果正在初始化,等待正在进行的初始化完成 if (initPromise && !forceReinit) { return initPromise; } // 开始新的初始化 initPromise = (async () => { try { // 1. 合并配置 const mergedConfig = mergeConfig(config); // 2. 设置全局配置(供 Metro 配置等使用) setGlobalConfig(mergedConfig); // 2.5 初始化 HMR Client (开发环境) if (__DEV__ && mergedConfig.devServer) { HMRClient.getInstance().setup( mergedConfig.devServer.host, mergedConfig.devServer.port ); } // 3. 获取 manifest let manifest: BundleManifest; try { manifest = await getManifestFromProvider(mergedConfig.manifestProvider); } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); console.error('[initMultiBundle] Failed to get manifest:', err); config.onError?.(err); return { success: false, error: err, }; } // 4. 设置自定义 ModuleLoader(如果提供) if (mergedConfig.moduleLoader) { ModuleRegistry.setModuleLoader(mergedConfig.moduleLoader); } // 5. 初始化 ModuleRegistry ModuleRegistry.init({ manifest }); // 6. 预加载模块 if (mergedConfig.preloadModules && mergedConfig.preloadModules.length > 0) { const preloadPromises = mergedConfig.preloadModules.map((moduleId) => preloadModule(moduleId).catch((error) => { // 预加载失败不影响初始化,只记录日志 console.warn(`[initMultiBundle] Preload module ${moduleId} failed:`, error); config.onError?.(error instanceof Error ? error : new Error(String(error))); }) ); await Promise.allSettled(preloadPromises); } isInitialized = true; return { success: true, manifest, }; } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); console.error('[initMultiBundle] Initialization failed:', err); config.onError?.(err); // 初始化失败时,允许下次重试 isInitialized = false; initPromise = null; return { success: false, error: err, }; } finally { // 如果强制重新初始化,清除 promise(允许下次调用) if (forceReinit) { initPromise = null; } } })(); return initPromise; } /** * 重置初始化状态(用于测试或特殊场景) */ export function resetInitState(): void { isInitialized = false; initPromise = null; }