🐞 fix(i18n): resolve translation loading issues in production build

This commit is contained in:
IGCrystal
2025-06-16 20:14:00 +08:00
parent 9838c2758b
commit 9d7ad7a18f
3 changed files with 179 additions and 30 deletions
+19 -20
View File
@@ -1,44 +1,43 @@
import { ref, computed, watchEffect } from 'vue';
import { I18nLoader } from './loader';
import { ref, computed } from 'vue';
import { translations as staticTranslations } from './translations';
import type { Locale } from './types';
// 全局状态
const currentLocale = ref<Locale>('zh-CN');
const loader = new I18nLoader();
const translations = ref<Record<string, any>>({});
// 加载器实例
let loaderInstance: I18nLoader | null = null;
/**
* 初始化i18n系统
*/
export async function initI18n(locale: Locale = 'zh-CN') {
loaderInstance = new I18nLoader();
currentLocale.value = locale;
// 加载初始翻译
await loadTranslations(locale);
// 加载静态翻译数据
loadTranslations(locale);
}
/**
* 加载翻译数据
* 加载翻译数据(现在从静态导入获取)
*/
async function loadTranslations(locale: Locale) {
if (!loaderInstance) {
throw new Error('I18n not initialized. Call initI18n() first.');
}
function loadTranslations(locale: Locale) {
try {
const data = await loaderInstance.loadLocale(locale);
translations.value = data;
const data = staticTranslations[locale];
if (data) {
translations.value = data;
} else {
console.warn(`Translations not found for locale: ${locale}`);
// 回退到中文
if (locale !== 'zh-CN') {
console.log('Falling back to zh-CN');
translations.value = staticTranslations['zh-CN'];
}
}
} catch (error) {
console.error(`Failed to load translations for ${locale}:`, error);
// 回退到中文
if (locale !== 'zh-CN') {
console.log('Falling back to zh-CN');
const fallbackData = await loaderInstance.loadLocale('zh-CN');
translations.value = fallbackData;
translations.value = staticTranslations['zh-CN'];
}
}
}
@@ -84,7 +83,7 @@ export function useI18n() {
const setLocale = async (newLocale: Locale) => {
if (newLocale !== currentLocale.value) {
currentLocale.value = newLocale;
await loadTranslations(newLocale);
loadTranslations(newLocale);
// 保存到localStorage
localStorage.setItem('astrbot-locale', newLocale);
+28 -10
View File
@@ -85,15 +85,10 @@ export class I18nLoader {
}
try {
// 使用fetch方式加载JSON文件
const modulePath = `/src/i18n/locales/${locale}/${moduleInfo.path}`;
const response = await fetch(modulePath);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// 使用动态import加载JSON文件,兼容构建和开发环境
const modulePath = `../locales/${locale}/${moduleInfo.path}`;
const module = await import(/* @vite-ignore */ modulePath);
const data = module.default || module;
// 缓存结果
this.cache.set(cacheKey, data);
@@ -105,7 +100,30 @@ export class I18nLoader {
return data;
} catch (error) {
console.error(`加载模块 ${moduleName} 失败:`, error);
return {};
// 回退方案:尝试使用fetch(开发环境)
try {
const modulePath = `/src/i18n/locales/${locale}/${moduleInfo.path}`;
const response = await fetch(modulePath);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// 缓存结果
this.cache.set(cacheKey, data);
// 更新模块信息
moduleInfo.loaded = true;
moduleInfo.data = data;
return data;
} catch (fetchError) {
console.error(`回退fetch加载也失败:`, fetchError);
return {};
}
}
}
+132
View File
@@ -0,0 +1,132 @@
// 静态导入所有翻译文件
// 这种方式确保构建时所有翻译都会被正确打包
// 中文翻译
import zhCNCommon from './locales/zh-CN/core/common.json';
import zhCNActions from './locales/zh-CN/core/actions.json';
import zhCNStatus from './locales/zh-CN/core/status.json';
import zhCNNavigation from './locales/zh-CN/core/navigation.json';
import zhCNHeader from './locales/zh-CN/core/header.json';
import zhCNChat from './locales/zh-CN/features/chat.json';
import zhCNExtension from './locales/zh-CN/features/extension.json';
import zhCNConversation from './locales/zh-CN/features/conversation.json';
import zhCNToolUse from './locales/zh-CN/features/tool-use.json';
import zhCNProvider from './locales/zh-CN/features/provider.json';
import zhCNPlatform from './locales/zh-CN/features/platform.json';
import zhCNConfig from './locales/zh-CN/features/config.json';
import zhCNConsole from './locales/zh-CN/features/console.json';
import zhCNAbout from './locales/zh-CN/features/about.json';
import zhCNSettings from './locales/zh-CN/features/settings.json';
import zhCNAuth from './locales/zh-CN/features/auth.json';
import zhCNChart from './locales/zh-CN/features/chart.json';
import zhCNDashboard from './locales/zh-CN/features/dashboard.json';
import zhCNAlkaidIndex from './locales/zh-CN/features/alkaid/index.json';
import zhCNAlkaidKnowledgeBase from './locales/zh-CN/features/alkaid/knowledge-base.json';
import zhCNAlkaidMemory from './locales/zh-CN/features/alkaid/memory.json';
import zhCNErrors from './locales/zh-CN/messages/errors.json';
import zhCNSuccess from './locales/zh-CN/messages/success.json';
import zhCNValidation from './locales/zh-CN/messages/validation.json';
// 英文翻译
import enUSCommon from './locales/en-US/core/common.json';
import enUSActions from './locales/en-US/core/actions.json';
import enUSStatus from './locales/en-US/core/status.json';
import enUSNavigation from './locales/en-US/core/navigation.json';
import enUSHeader from './locales/en-US/core/header.json';
import enUSChat from './locales/en-US/features/chat.json';
import enUSExtension from './locales/en-US/features/extension.json';
import enUSConversation from './locales/en-US/features/conversation.json';
import enUSToolUse from './locales/en-US/features/tool-use.json';
import enUSProvider from './locales/en-US/features/provider.json';
import enUSPlatform from './locales/en-US/features/platform.json';
import enUSConfig from './locales/en-US/features/config.json';
import enUSConsole from './locales/en-US/features/console.json';
import enUSAbout from './locales/en-US/features/about.json';
import enUSSettings from './locales/en-US/features/settings.json';
import enUSAuth from './locales/en-US/features/auth.json';
import enUSChart from './locales/en-US/features/chart.json';
import enUSDashboard from './locales/en-US/features/dashboard.json';
import enUSAlkaidIndex from './locales/en-US/features/alkaid/index.json';
import enUSAlkaidKnowledgeBase from './locales/en-US/features/alkaid/knowledge-base.json';
import enUSAlkaidMemory from './locales/en-US/features/alkaid/memory.json';
import enUSErrors from './locales/en-US/messages/errors.json';
import enUSSuccess from './locales/en-US/messages/success.json';
import enUSValidation from './locales/en-US/messages/validation.json';
// 组装翻译对象
export const translations = {
'zh-CN': {
core: {
common: zhCNCommon,
actions: zhCNActions,
status: zhCNStatus,
navigation: zhCNNavigation,
header: zhCNHeader
},
features: {
chat: zhCNChat,
extension: zhCNExtension,
conversation: zhCNConversation,
tooluse: zhCNToolUse,
provider: zhCNProvider,
platform: zhCNPlatform,
config: zhCNConfig,
console: zhCNConsole,
about: zhCNAbout,
settings: zhCNSettings,
auth: zhCNAuth,
chart: zhCNChart,
dashboard: zhCNDashboard,
alkaid: {
index: zhCNAlkaidIndex,
'knowledge-base': zhCNAlkaidKnowledgeBase,
memory: zhCNAlkaidMemory
}
},
messages: {
errors: zhCNErrors,
success: zhCNSuccess,
validation: zhCNValidation
}
},
'en-US': {
core: {
common: enUSCommon,
actions: enUSActions,
status: enUSStatus,
navigation: enUSNavigation,
header: enUSHeader
},
features: {
chat: enUSChat,
extension: enUSExtension,
conversation: enUSConversation,
tooluse: enUSToolUse,
provider: enUSProvider,
platform: enUSPlatform,
config: enUSConfig,
console: enUSConsole,
about: enUSAbout,
settings: enUSSettings,
auth: enUSAuth,
chart: enUSChart,
dashboard: enUSDashboard,
alkaid: {
index: enUSAlkaidIndex,
'knowledge-base': enUSAlkaidKnowledgeBase,
memory: enUSAlkaidMemory
}
},
messages: {
errors: enUSErrors,
success: enUSSuccess,
validation: enUSValidation
}
}
};
export type TranslationData = typeof translations;