create-tengits-app
Version:
🚀 快速创建基于 React + Rsbuild + TypeScript + Tailwind CSS + Antd 的现代前端项目脚手架
141 lines (122 loc) • 4.05 kB
JavaScript
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
// 获取存储的语言设置,如果没有则默认使用中文
// 根据浏览器语言自动检测并映射到支持的语言
function getBrowserLanguage() {
const browserLang = navigator.language.toLowerCase();
// 映射浏览器语言到支持的语言代码
if (browserLang.startsWith('zh')) {
return 'zh';
}
else if (browserLang.startsWith('en')) {
return 'en';
}
else if (browserLang.startsWith('fr')) {
return 'fr';
}
else if (browserLang.startsWith('de')) {
return 'de';
}
else if (browserLang.startsWith('es')) {
return 'es';
}
// 默认返回中文
return 'zh';
}
// 获取存储的语言设置,如果没有则使用浏览器语言检测
const savedLanguage = localStorage.getItem('language') || getBrowserLanguage();
const aiI18n = i18n.createInstance();
// 创建新的i18n实例,避免与其他实例冲突
const allNamespaces = ['Common'];
// 创建新的i18n实例,避免与其他实例冲突
const nsMap = {
// '/doc': ['ReportConfiguration', 'Common'],
};
// 缓存已加载的翻译数据
const translationCache = new Map();
// 缓存进行中的请求,避免重复请求
const pendingRequests = new Map();
export const initializeAiI18n = async (options = {}) => {
// 使用Backend和initReactI18next插件
// 根据当前路由设置默认命名空间
const currentPath = window.location.pathname;
let defaultNS = 'Common'; // 默认命名空间
// 根据路由路径设置对应的命名空间
// 使用nsMap来映射路径到命名空间
for (const [path, namespace] of Object.entries(nsMap)) {
if (currentPath.includes(path)) {
defaultNS = namespace;
break;
}
}
// 更新默认命名空间
if (options.defaultNS) {
defaultNS = options.defaultNS;
}
// 只加载必要的命名空间,而不是所有命名空间
const initialNamespaces = Array.isArray(defaultNS) ? defaultNS : [defaultNS]; // 只加载默认命名空间和回退命名空间
// 使用Backend和initReactI18next插件
return aiI18n.use(Backend)
.use(initReactI18next)
.init({
nsSeparator: '/',
partialBundledLanguages: true,
lng: savedLanguage,
fallbackLng: savedLanguage, // 明确设置 fallback 语言为中文
ns: allNamespaces, // 指定命名空间
// ns: initialNamespaces, // 只指定初始命名空间
defaultNS, // 默认命名空间
fallbackNS: 'Common', // 回退命名空间
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
interpolation: {
escapeValue: false, // react already safes from xss
},
});
};
/**
* 修改命名空间的方法
* @param ns - 新的命名空间
*/
export const changeNamespace = (ns) => {
return new Promise((resolve, reject) => {
if (ns) {
aiI18n.loadNamespaces(ns)
.then(() => {
aiI18n.setDefaultNamespace(ns);
console.log('Current namespace:', aiI18n);
resolve();
})
.catch((error) => {
console.error('Failed to load namespace:', error);
reject(error);
});
}
else {
resolve();
}
});
};
/**
* 多命名空间翻译方法 - 注意:含{{}}变量的key必须使用i18n.t而不是该t,否则会报错
* @param key - 翻译键值
* @param namespace - 命名空间,可选
* @returns 翻译后的文本
*/
export const t = (key, namespace) => {
if (namespace) {
return aiI18n.t(key, { ns: namespace });
}
const title = aiI18n.t(key);
return title;
};
/**
* 预加载多个命名空间
* @param namespaces - 命名空间数组
*/
export const loadMultipleNamespaces = (namespaces) => {
return Promise.all(namespaces.map(ns => aiI18n.loadNamespaces(ns)));
};
export default aiI18n;