diff --git a/src/utils/federationLoader.ts b/src/utils/federationLoader.ts index 1b368373..52febc3b 100644 --- a/src/utils/federationLoader.ts +++ b/src/utils/federationLoader.ts @@ -6,12 +6,55 @@ import { // @ts-ignore } from 'virtual:__federation__' +// 扩展全局接口,添加federation所需的共享作用域 +declare global { + interface Window { + __rf_placeholder__shareScope?: Record + vue?: any + vuetify?: any + pinia?: any + 'vue-i18n'?: any + 'vue-router'?: any + axios?: any + } +} + // 定义远程模块接口 interface RemoteModule { id: string url: string } +/** + * 初始化共享作用域 + */ +function initShareScope() { + // 确保全局共享作用域存在 + if (!window.__rf_placeholder__shareScope) { + window.__rf_placeholder__shareScope = {} + } + // 为共享模块设置默认作用域 + const shared = ['vue', 'vuetify', 'pinia', 'vue-i18n', 'vue-router', 'axios'] + shared.forEach(lib => { + if (window.__rf_placeholder__shareScope) { + window.__rf_placeholder__shareScope[lib] = { default: { get: () => (window as any)[lib] } } + } + }) + console.log('已初始化共享作用域:', window.__rf_placeholder__shareScope) +} + +/** + * 添加一个dummy远程模块以解决生产环境中的共享作用域问题 + */ +function addDummyRemote() { + __federation_method_setRemote('dummy', { + url: () => Promise.resolve(''), + format: 'esm', + from: 'vite', + shareScope: 'default', + }) +} + /** * 加载远程组件 * @param id 远程模块ID @@ -40,6 +83,13 @@ async function fetchRemoteModules(): Promise { } } +/** + * 生成唯一的版本标记用于防止缓存 + */ +function generateVersionTag(): string { + return `v=${Date.now()}` +} + /** * 动态注入Federation Remote模块 * @param modules 远程模块列表 @@ -55,10 +105,17 @@ function injectRemoteModule(module: RemoteModule): void { if (apiBase.endsWith('/')) { apiBase = apiBase.slice(0, -1) } + + // 添加版本标记防止缓存 + const versionTag = generateVersionTag() + const remoteUrl = `${baseUrl.origin}/${apiBase}${module.url}` + const urlWithVersion = remoteUrl.includes('?') ? `${remoteUrl}&${versionTag}` : `${remoteUrl}?${versionTag}` + __federation_method_setRemote(module.id, { - url: () => Promise.resolve(`${baseUrl.origin}/${apiBase}${module.url}`), + url: () => Promise.resolve(urlWithVersion), format: 'esm', from: 'vite', + shareScope: 'default', }) console.log('已注入远程模块:', module) } @@ -68,6 +125,12 @@ function injectRemoteModule(module: RemoteModule): void { */ export async function loadRemoteComponents(): Promise { try { + // 初始化共享作用域 + initShareScope() + + // 添加dummy远程模块解决生产环境问题 + addDummyRemote() + // 获取远程模块列表 const modules = await fetchRemoteModules()