跳到主要内容前端国际化最佳实践 | 极客日志JavaScriptNode.js大前端
前端国际化最佳实践
前端国际化涉及多语言支持与格式本地化。硬编码字符串导致维护困难,推荐采用 i18next 等专业库统一管理资源。方案涵盖参数化翻译、浏览器语言自动检测、日期时间数字货币格式化及 RTL 布局支持。配合懒加载与自动提取工具可提升开发效率与用户体验。
imJackJia18 浏览 常见误区
前端国际化?这不是大公司才需要的吗?
"我的网站只面向国内用户,要什么国际化"——结果业务拓展到海外,临时抱佛脚;
"我直接用中文写死,多简单"——结果需要支持英文时,满世界找字符串;
"我用 Google 翻译,多快"——结果翻译质量差,用户体验差。
国际化不是可选的,而是现代前端开发的标配!
为什么你需要这个?
- 全球用户覆盖:吸引来自不同国家和地区的用户
- 业务拓展:为未来的海外业务做准备
- 用户体验:让用户使用自己熟悉的语言
- 品牌形象:展现专业、全球化的品牌形象
- 合规要求:满足某些国家的语言法规要求
反面教材
function Header() {
return (
<div className="header">
<h1>欢迎来到我的网站</h1>
<nav>
<a href="/">首页</a>
<a href="/about">关于我们</a>
<a href="/contact">联系我们</a>
</nav>
</div>
);
}
function App() {
const [language, setLanguage] = useState('zh');
= () => {
texts = {
: { : , : , : },
: { : , : , : }
};
texts[language][key];
};
(
);
}
const
getText
key
const
zh
welcome
'欢迎'
about
'关于我们'
contact
'联系我们'
en
welcome
'Welcome'
about
'About Us'
contact
'Contact Us'
return
return
<div>
<button onClick={() => setLanguage('zh')}>中文</button>
<button onClick={() => setLanguage('en')}>English</button>
<h1>{getText('welcome')}</h1>
</div>
正确的做法
1. 使用专业的国际化库
安装依赖:npm install i18next react-i18next
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import zh from './locales/zh.json';
import en from './locales/en.json';
import ja from './locales/ja.json';
i18n
.use(initReactI18next)
.init({
resources: {
zh: { translation: zh },
en: { translation: en },
ja: { translation: ja }
},
lng: 'zh',
fallbackLng: 'en',
interpolation: { escapeValue: false },
detection: {
order: ['navigator', 'localStorage', 'cookie'],
caches: ['localStorage', 'cookie']
}
});
export default i18n;
定义翻译资源文件 locales/zh.json:
{
"welcome": "欢迎来到我的网站",
"nav": {
"home": "首页",
"about": "关于我们",
"contact": "联系我们"
},
"greeting": "你好,{{name}}!",
"count": "你有 {{count}} 条消息",
"date": "今天是 {{date}}"
}
import React from 'react';
import { useTranslation } from 'react-i18next';
function Header() {
const { t } = useTranslation();
return (
<div className="header">
<h1>{t('welcome')}</h1>
<nav>
<a href="/">{t('nav.home')}</a>
<a href="/about">{t('nav.about')}</a>
<a href="/contact">{t('nav.contact')}</a>
</nav>
</div>
);
}
function Greeting({ name }) {
const { t } = useTranslation();
return (
<div>
<p>{t('greeting', { name })}</p>
</div>
);
}
2. 语言切换组件
import React from 'react';
import { useTranslation } from 'react-i18next';
function LanguageSwitcher() {
const { i18n } = useTranslation();
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
};
return (
<div className="language-switcher">
<button onClick={() => changeLanguage('zh')}>中文</button>
<button onClick={() => changeLanguage('en')}>English</button>
<button onClick={() => changeLanguage('ja')}>日本語</button>
</div>
);
}
3. 日期和时间本地化
import React from 'react';
import { useTranslation } from 'react-i18next';
import { format } from 'date-fns';
import { zhCN, enUS, ja } from 'date-fns/locale';
function LocalizedDate() {
const { i18n } = useTranslation();
const currentDate = new Date();
const getLocale = () => {
switch (i18n.language) {
case 'zh': return zhCN;
case 'en': return enUS;
case 'ja': return ja;
default: return enUS;
}
};
const formattedDate = format(currentDate, 'yyyy 年 MM 月 dd 日 EEEE', { locale: getLocale() });
return (
<div>
<p>{formattedDate}</p>
</div>
);
}
4. 数字和货币本地化
function LocalizedNumber({ number }) {
const { i18n } = useTranslation();
const formattedNumber = new Intl.NumberFormat(i18n.language).format(number);
return (
<div>
<p>{formattedNumber}</p>
</div>
);
}
function LocalizedCurrency({ amount, currency }) {
const { i18n } = useTranslation();
const formattedCurrency = new Intl.NumberFormat(i18n.language, {
style: 'currency',
currency: currency
}).format(amount);
return (
<div>
<p>{formattedCurrency}</p>
</div>
);
}
5. RTL 语言支持
[dir="rtl"] {
text-align: right;
}
[dir="rtl"] .nav {
flex-direction: row-reverse;
}
import React from 'react';
import { useTranslation } from 'react-i18next';
function App() {
const { i18n } = useTranslation();
React.useEffect(() => {
const rtlLanguages = ['ar', 'he', 'fa'];
document.documentElement.dir = rtlLanguages.includes(i18n.language) ? 'rtl' : 'ltr';
}, [i18n.language]);
return (
<div>
<LanguageSwitcher />
<Header />
<Greeting name="张三" />
<LocalizedDate />
<LocalizedNumber number={1234567.89} />
<LocalizedCurrency amount={100} currency="CNY" />
</div>
);
}
6. 懒加载与自动提取
使用 i18next-http-backend 加载翻译:
import Backend from 'i18next-http-backend';
i18n
.use(Backend)
.use(initReactI18next)
.init({
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
使用 i18next-scanner 自动提取翻译:
{
"scripts": {
"i18n:scan": "i18next-scanner --config i18next-scanner.config.js src"
}
}
module.exports = {
input: ['src/**/*.{js,jsx,ts,tsx}'],
output: './locales',
options: {
lngs: ['zh', 'en', 'ja'],
defaultLng: 'zh',
ns: ['translation'],
defaultValue: (lng, ns, key) => key,
resourceKeySeparator: '.',
nsSeparator: ':',
interpolation: { prefix: '{{', suffix: '}}' }
}
};
核心要点
记住,国际化不仅仅是翻译文本,还包括日期、时间、数字、货币等格式的本地化,以及 RTL(从右到左)语言的支持。它是你网站走向世界的必备技能!
总结
- 使用专业库:如 i18next、react-intl 等
- 统一管理翻译资源:将翻译文本放在单独的 JSON 文件中
- 支持参数化翻译:处理带变量的文本
- 自动检测语言:根据用户浏览器设置自动切换语言
- 本地化格式:处理日期、时间、数字、货币的本地化
- RTL 支持:支持从右到左的语言如阿拉伯语
- 懒加载翻译:按需加载翻译资源,减少包大小
- 自动提取翻译:使用工具自动提取需要翻译的字符串
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online