简单介绍我们的项目
一个基于next的国际化ssr项目
前端国际化是什么?
在web站点中,通过切换国家或地区实现站点的语言切换. 比如中文, 英语, 西语...
为什么是i18n: i到n之间有18个字母
用到了哪些框架?
react-intl
国际化的三个重要部分
- react-intl库: 提供翻译context, 方便收集分发翻译, 日期格式化和货币格式化等功能
- i18n-www静态仓库: 存放不同语言的json文件
- onesky翻译平台: 一个专门托管语言的json文件, 方便翻译人员的操作台, 提供了上传下载接口, 功能齐全
流程图
- 第一步: 本地增加一个字段, 采用base语言en进行开发, 完成开发后上传到onesky, 通知运营翻译该字段
- 第二步: 下载最新的翻译json文件,上传到i18n-www仓库并发布该项目, 配置中心更新翻译时间戳, 站点翻译被更新
拉取翻译文件的流程
- 有刷新的访问国际化站点时候
- 在国际化站点中进行无刷新的路由跳转
解释一下关于[拉取翻译文件的流程]中的node端缓存和浏览器端缓存
node缓存
- node连接配置中心, 更新配置中心时间戳, 202208301516
- 时间戳发生变化, node服务更新缓存key为: i18n_202208301516_1, 并把时间戳写到cookie中
浏览器缓存
- 在站点无刷跳转时, 从cookie中读取时间戳, 然后根据时间戳相应的key(i18n_202208301516_1)去读取对应的localStorage中的缓存
202208301516: 表示时间戳, 1: 表示地区
上代码
- 基于next框架的ssr项目, 在_app.tsx中:
import { IntlProvider } from 'react-intl';
// messages的数据就是翻译的json文件 - en.json
const messages = {
g0: 'download',
g1: 'SignUp'
};
<IntlProvider
messages={messages}
locale: 'en'
formats: {
date: {
normal: {
hour12: false,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
}
}
}
>
<Component />
</IntlProvider>
- 国际化字段为了确保不出现重复, 所以把所有的字段统一到locale/global.ts文件中
import { defineMessages } from 'react-intl';
const locale = defineMessages({
download: {
id: 'g0',
defaultMessage: 'Download'
},
startFreeTrial: {
id: 'g1',
defaultMessage: 'Start Free Trial'
}
});
解释: 这里的id必须是唯一的, 不能重复. 因为这才是最后生成的en.json文件中的key
同样出于考虑en.json文件大小问题, id = 'g0' 而不是 id = 'download'
- 在src/components/download/index.tsx组件中
import { useIntl } from 'react-intl';
import GLocale from '@locale/global';
const View = () => {
const { formatMessage: fm }= useIntl();
return <div>{fm(Glocale.startFreeTrial)}</div>
};