import { createI18n } from "vue-i18n"; import { localeMap, type LocaleType } from "./config"; import { setHtmlPageLang, setLoadLocalePool } from "./helper"; import { useLocaleStoreWithOut } from "../store/modules/locale"; import enUS from "./lang/en_US"; import zhCN from "./lang/zh_CN"; /** Vite/ESM:default 导出即 { message, ... };部分 webpack 链路上可能再包一层 .default,两处都兼容 */ function getLocaleMessages(mod: typeof zhCN | typeof enUS) { type Bundle = { message?: Record }; const withMaybeDefault = mod as Bundle & { default?: Bundle }; const bundle = withMaybeDefault.default ?? withMaybeDefault; return bundle.message ?? {}; } /** * 获取宿主(基座)语言。 * qiankun 微前端场景下,基座会在 window 上注入全局 LtConfig.locale("zh"/"en" 等), * 组件库的语言必须跟随基座;若只读自己 storage 里的 LOCALE__(默认 zh_CN), * 宿主切英文后"序号"等库内部文案会仍停留在中文。 */ function getHostLocale(): LocaleType | undefined { const hostLocale = (globalThis as any)?.LtConfig?.locale; if (typeof hostLocale == "string" && hostLocale) { const lower = hostLocale.toLowerCase(); if (lower.startsWith("en")) return localeMap.en_US; if (lower.startsWith("zh")) return localeMap.zh_CN; } return undefined; } function createI18nOptions() { const localeStore = useLocaleStoreWithOut(); const locale = getHostLocale() ?? localeStore.getLocale; //与宿主语言对齐后写回本地存储,保证库内其他读取 locale 的模块(antd 包装语言等)一致 if (localeStore.getLocale !== locale) { localeStore.setLocale(locale); } const defaultLocal = locale == "zh_CN" ? zhCN : enUS; const message = getLocaleMessages(defaultLocal); setHtmlPageLang(locale); setLoadLocalePool((loadLocalePool) => { loadLocalePool.push(locale); }); return { locale, legacy: false, fallbackLocale: localeMap.zh_CN, // set fallback locale messages: { [locale]: message as { [key: string]: string }, }, globalInjection: true, silentTranslationWarn: true, // true - warning off missingWarn: false, silentFallbackWarn: true, }; } const options = createI18nOptions(); export const i18n = createI18n(options); /** * 运行时把库内 i18n 切到目标语言(含语言包装载与本地存储同步)。 * 库的 i18n 是独立实例,宿主通过 qiankun onGlobalStateChange 免刷新切语言时, * 必须由这里同步,否则"序号"等库内部文案不会跟随变化。 */ function syncI18nLocale(locale: LocaleType) { const local = locale == "zh_CN" ? zhCN : enUS; i18n.global.setLocaleMessage(locale, getLocaleMessages(local) as any); (i18n.global.locale as any).value = locale; useLocaleStoreWithOut().setLocale(locale); } //监听基座语言变化(qiankun 免刷新切换场景:基座更新全局 LtConfig.locale) let lastHostLocale = (globalThis as any)?.LtConfig?.locale; setInterval(() => { const hostLocale = (globalThis as any)?.LtConfig?.locale; if (typeof hostLocale == "string" && hostLocale && hostLocale !== lastHostLocale) { lastHostLocale = hostLocale; const target = getHostLocale(); if (target && (i18n.global.locale as any).value !== target) { syncI18nLocale(target); } } }, 1000); // setup i18n instance with global // export function setupI18n(app: App) { // app.use(i18n); // }