现在国际化已经很普遍了,之前的国际化都是在public文件下面建立翻译文件夹,然后再分别建立不同语言的文件夹和对应的json文件。图如下图
项目是react + antdm
然后在src文件下面建一个i18n.js/ts文件
js
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import Backend from 'i18next-http-backend'
import Cookies from 'js-cookie'
let lang = Cookies.get('lang') || 'zh' // 这个页面是内嵌到flutter的 需要cookie接收 flutter 传过来的参数
console.log('lang', lang)
i18n
.use(Backend)
.use(initReactI18next)
.init({
debug: false,
interpolation: {
escapeValue: false // not needed for react as it escapes by default
},
fallbackLng: 'zh',
lng: lang,
backend: {
loadPath: `/locales/${lang}/translation.json`,
requestOptions: {
cache: 'no-store'
}
}
})
export default i18n
然后再index入口文件里面
js
import ReactDOM from 'react-dom/client'
import { HashRouter, BrowserRouter } from 'react-router-dom'
import React, { Suspense } from 'react'
import './index.scss'
import './utils/rem'
import { Provider } from 'react-redux'
import store from './store'
import RouterEnter from './router/index'
import { LoadingElement } from '@/components/loading'
import { SafeArea, ConfigProvider } from 'antd-mobile'
import i18n from '@/i18n'
import Cookies from 'js-cookie'
import {antdLang} from '@/constants/antdLang' // 这个是antm的国际化
let lang = Cookies.get('lang') || 'zh' // 切换语言
console.log('lang', lang)
i18n.changeLanguage(lang)
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<ConfigProvider locale={antdLang[lang]}>
<Provider store={store}>
<BrowserRouter>
<Suspense fallback={LoadingElement}>
<SafeArea position="top" />
<RouterEnter></RouterEnter>
<SafeArea position="bottom" />
</Suspense>
</BrowserRouter>
</Provider>
</ConfigProvider>
)
@/constants/antdLang 文件里面
js
import enUS from 'antd-mobile/es/locales/en-US'
import zhCN from 'antd-mobile/es/locales/zh-CN'
const antdLang = {
"zh": zhCN,
"en": enUS
}
export { antdLang }
至此,i18n就基本配置完了
使用的话很简单
js
import { useTranslation } from 'react-i18next'
const Page = () => {
const { t } = useTranslation()
return (
<div>
{{t('otcIndex.sellPage.min')}}
</div>
)
}
export default Page
react-i18next 这个包提供了一个简单而灵活的解决方案,允许开发者为他们的React应用添加多语言功能。通过react-i18next,开发者可以方便地管理和加载不同语言的翻译资源,使得应用能够根据不同用户的语言环境显示对应的语言内容
i18next-http-backend i18next本身并不直接提供从后端服务器加载翻译文件的功能。为了实现这一功能,就需要使用一个插件,比如i18next-http-backend,这个包允许i18next通过HTTP请求从后端服务器获取翻译文件,通过配置i18next-http-backend插件,你可以指定后端服务器的地址和翻译文件的路径。也就是说,在i18next需要加载某个语言的翻译文件时,它会发送一个HTTP请求到指定的后端服务器地址,从服务器上获取相应的翻译文件。
如下图:
然后i18next会在需要时从后端服务器加载相应的翻译文件,以实现多语言切换和显示。需要注意的是,i18next-http-backend通常用于开发环境,以便能够灵活地管理和更新翻译文件。但在生产环境中,你可能需要考虑其他更高效的翻译文件加载方式,比如将翻译文件作为静态资源打包到你的应用程序中,并在初始化i18next时直接指定这些文件的路径。这样,翻译文件就会随着应用程序一起部署,并在运行时被i18next直接加载,或者使用CDN等方式进行缓存和优化。
突然甲方来了新需求,说什么他们那边做了缓存,但是缓存对象没有json格式
需要我们这边把json转为js。。。。(最后知道真相的我眼泪掉下来。。。。)
只能去认真翻看 i18next的官网 然后看到了这个
翻译过来的意思大概是:初始化的资源(如果不使用后端插件或不使用addResourceBundle)
那就正好和 i18next-http-backend 提示的一样 把资源(国际化翻译文件)放在项目中
js
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import Backend from 'i18next-http-backend'
import Cookies from 'js-cookie'
let lang = Cookies.get('lang') || 'zh'
console.log('lang', lang)
i18n
// .use(Backend)
.use(initReactI18next)
.init({
debug: false,
interpolation: {
escapeValue: false // not needed for react as it escapes by default
},
fallbackLng: 'zh',
lng: lang,
// backend: {
// loadPath: `/locales/${lang}/translation.json`,
// requestOptions: {
// cache: 'no-store'
// }
// }
resources: {
zh: {
translation:require('./locales/zh/translation.json') // 指定中文翻译文件的路径
}
}
})
export default i18n
测试了一下,没有任何问题
然后再来解决把json文件变为js文件 还得满足 require 导入
所以考虑用 CommonJS 的 module.exports
js
/*
i18n 文件里面就直接引入js文件了
zh: {
translation:require('./locales/zh/translation.js') // 指定中文翻译文件的路径
}
*/
// zh下的translation.js文件
module.exports = {
"btn.cancel": "取消",
"btn.next": "下一步",
"btn.noData": "暂无数据",
"btn.loading": "加载中",
"btn.timedOut": "请求超时,请稍后重试!",
"btn.checkConnection": "请求失败, 请检查网络连接",
"btn.unknownError": "未知错误",
"btn.200": "200 - 请求成功",
"btn.201": "201 - 请求已创建",
"btn.202": "202 - 请求已接受",
"btn.400": "400 - 错误请求!",
"btn.401": "401 - 用户没有权限!",
"btn.403": "403 - 拒绝访问!",
"btn.404": "404 - 请求错误, 未找到该资源!",
"btn.500": "500 - 服务器发生错误,请检查服务器!",
"btn.502": "502 - 网关错误!",
"btn.503": "503 - 服务不可用,服务器暂时过载或维护!",
"btn.504": "504 - 连接超时!",
"status.progress": "交易处理中",
"status.success": "交易成功",
"status.fail": "交易失败",
"success.copy": "复制成功",
"sell.num":"请输入{{coinMinAmount }}-{{coinMaxAmount}}的出售数量"
}
大功告成!