最近业务需要,调研了下主流的国际化方案,顺便做个记录。
1、 react-intl,按需加载 intl 作为补丁。react-intl 由 Yahoo 研发。是 Format.js 生态的一部分。
先在 locales 里定义语言,可以用 .ts 也可以用 .json 。
// src/locales/zh-CN.ts
export default {
welcome: '欢迎光临 Umi 的世界!',
};
然后使用时用 FormattedMessage 渲染。
import { FormattedMessage } from 'react-intl';
<FormattedMessage id="welcome" defaultMessage="Welcome" />
也可以拿到 intl 然后去 formatMessage。不推荐,它脱离了 React 的生命周期,可能导致切换语言时无法触发 DOM 的 re-render 。
import { useIntl } from 'react-intl';
const intl = useIntl();
intl.formatMessage({ id: 'welcome' });
支持动态插值,比如 Hello {name}
,<FormattedMessage id="welcome" values={{name: 'fooo'}} />
。
支持切换。
import { setLocale } from 'react-intl';
setLocale('en-US');
// 切换但不刷新
setLocale('en-US', false);
// 切换到默认语言
setLocale();
支持通过配置实现路由 title 的国际化。
2、react-i18next,基于 i18next。周下载 300W+,是 react-intl 的 2-3 倍。
相比 react-intl,react-i18next 的优点是:
1)生态好,大型应用用 react-i18next 更合适
2)国际化文件支持按需加载,性能上会更好
3)SSR 友好
4)TypeScript 支持友好(?)
5)通过 Trans 组件支持复杂的 JSX 内容翻译(句子翻译)
先初始化 i18n 。(注:http backend 通常可以搭配 localstorage-backend 做缓存)
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n
// 异步加载国际化数据
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
// options: https://www.i18next.com/overview/configuration-options & https://react.i18next.com/latest/i18next-instance
.init({});
在 public/locales/zh/translation.json 中定义。
{
"welcome": "欢迎来到 TNF !",
"getting-started": "编辑 <1>src/App.zh-CN.js</1> 快速开始。"
}
然后通过 useTranslation 使用(class 可以用 withTranslation hoc)。
import { useTranslation } from 'react-i18next';
const { t, i18n } = useTranslation();
t('welcome')
也可以用 Trans 组件翻译整段 jsx。
import { Trans } from 'react-i18next';
<Trans i18nKey="getting-started">
To get started, edit <code>src/App.js</code> and save to reload.
</Trans>
加 TypeScript 类型。
import "i18next";
import translation from "locales/en/translation.json";
declare module "i18next" {
interface CustomTypeOptions {
resources: {
translation: typeof translation;
}
}
}
本篇已被阅读 次