ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

react项目国际化需求开发:umi框架下用plugin-locale插件做多语言版本

react项目国际化需求开发:umi框架下用plugin-locale插件做多语言版本 1. umi 项目国际化改造从中文单语到中英双语切换的完整落地react 项目国际化需求开发这件事说难不难说简单也容易踩坑。umi 框架本身集成了umijs/plugin-locale插件它基于 react-intl 封装能帮我们把多语言文案、路由标题、菜单名称统一管理起来。这篇文章聚焦 umi 项目中基于 plugin-locale 插件落地国际化版本覆盖 locale 目录组织、菜单与路由文案抽取、切换语言与默认语言配置给出可复制的config.ts与 locales 文件配置并演示切换语言后页面文案与路由标题同步生效的验证步骤。适合谁看如果你手上有一个已经跑起来的 umi 项目产品突然要求加个中英文切换或者你正在做海外版本、需要按浏览器语言自动匹配那这篇就是给你准备的。我会把配置、目录结构、组件内调用、路由标题同步、常见报错排查都走一遍尽量做到复制粘贴就能跑。先说清楚 plugin-locale 能做什么它提供useIntl、setLocale、getLocale、formatMessage等 API支持locale目录下按语言分文件支持config.ts里配置默认语言和语言列表还支持和 umi 的路由title字段联动。也就是说页面里的按钮文案、菜单名、浏览器标签页标题都能跟着语言切换一起变。我试过在一个中等规模的后台项目里做这套改造最深的体会是目录结构和 key 命名规范如果一开始没定好后面文案一多就会乱。所以下面我会先讲目录怎么组织再讲配置怎么写最后讲怎么验证。2. TaoToken 前置准备给国际化项目接一个稳定的模型调用入口做国际化项目的时候经常需要调用大模型来批量翻译文案、生成 key、校对英文表达。这时候一个稳定的 API 入口就很重要。TaoToken 提供统一的模型调用地址官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 不带 UTM 参数。为什么国际化场景会用到它举个例子你有一份zh-CN.ts里面几百个中文 key要生成对应的en-US.ts。手动翻译又慢又容易漏。你可以写个脚本把中文文案批量发给模型让它返回英文再写回文件。这个过程需要一个能稳定调用的接口TaoToken 的 API 就派上用场了。前置准备分三步。第一步去官网注册账号拿到 API Key。第二步在控制台里确认你要用的模型 ID比如常用的对话模型。第三步把 Base URL、Key、Model ID 这三件套记下来后面写脚本或者配置工具都要用。这里要提醒一句TaoToken 是模型调用入口不是编辑器替代品也不是让你把生产数据库直连上去的东西。它的定位是帮你完成翻译、校对、生成这类文本任务。你可以在本地脚本里调用也可以在 CI 流程里调用但不要把 Key 硬编码到前端代码里那样会泄露。如果你只是偶尔翻译几个文件用模型对话页面手动贴文案也行地址是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果要长期做国际化、频繁生成多语言文件建议用 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 配合脚本自动化。拿到 Key 之后你可以先写一个最小的 Node 脚本测试一下连通性。比如用fetch发一个请求确认返回正常。这一步别跳过因为后面批量翻译文案时如果 Key 或 Base URL 写错会浪费很多时间排查。3. 可复制配置config.ts 与 locales 目录的完整写法这一节是核心我直接把可复制的配置贴出来。先说目录结构。在 umi 项目里国际化文件默认放在src/locales下按语言分文件src/ locales/ zh-CN.ts en-US.ts pages/ Home/ index.tsx app.tsx config.tszh-CN.ts内容示例export default { menu.home: 首页, menu.about: 关于我们, home.title: 欢迎来到国际化演示, home.switch: 切换语言, home.chinese: 中文, common.confirm: 确认, common.cancel: 取消, common.prompt: 提示, common.noPermissions: 暂无权限, };en-US.ts内容示例export default { menu.home: Home, menu.about: About Us, home.title: Welcome to i18n Demo, home.switch: Switch Language, home.chinese: Chinese, common.confirm: Confirm, common.cancel: Cancel, common.prompt: Prompt, common.noPermissions: No Permission, };注意 key 的命名规范用点号分层比如menu.home、home.title、common.confirm。这样后面文案多了也好找。不要用中文当 key也不要用拼音英文语义化 key 最稳。接下来是config.ts里的配置。umi 的 plugin-locale 需要在 config 里声明import { defineConfig } from umi; export default defineConfig({ locale: { default: zh-CN, antd: true, baseNavigator: true, baseSeparator: -, }, routes: [ { path: /, component: /pages/Home, title: menu.home, }, { path: /about, component: /pages/About, title: menu.about, }, ], });这里几个参数解释一下。default: zh-CN是默认语言用户第一次进来如果没匹配到浏览器语言就用这个。antd: true表示同时切换 antd 组件的语言包比如日期选择器、分页组件会跟着变。baseNavigator: true表示优先读取浏览器语言比如用户浏览器是 en-US就自动用英文。baseSeparator: -是语言代码的分隔符zh-CN 这种格式。路由里的title: menu.home是关键。它让浏览器标签页标题也走国际化。你不需要在组件里手动document.title ...umi 会自动根据当前语言去 locales 文件里找对应的值。如果你用的是 umi 4配置写法基本一致但要注意locale配置项的位置。umi 4 里插件名可能略有不同确认umijs/plugin-locale已经安装。安装命令npm install umijs/plugin-locale --save或者用 pnpmpnpm add umijs/plugin-locale装完之后重启 dev server让插件生效。这一步很多人会忘改完 config 不重启然后发现useIntl报错其实是插件没加载。4. 验证请求与成功结果切换语言后文案与路由标题同步生效配置写完了怎么验证我分三步走。第一步在组件里用useIntl和setLocale。第二步加一个语言切换下拉框。第三步观察页面文案和浏览器标签页标题是否同步变化。先看组件代码import React from react; import { useIntl, setLocale, getLocale } from umi; import { Select } from antd; const Home () { const intl useIntl(); const lang getLocale(); const changeLocale (value: string) { setLocale(value, true); }; return ( div style{{ padding: 24 }} h1{intl.formatMessage({ id: home.title })}/h1 Select defaultValue{lang} style{{ width: 120 }} onChange{changeLocale} options{[ { value: zh-CN, label: 中文 }, { value: en-US, label: English }, ]} / p{intl.formatMessage({ id: home.chinese })}/p /div ); }; export default Home;这里setLocale(value, true)的第二个参数true表示刷新页面。为什么要刷新因为有些文案是在组件初始化时读取的不刷新可能不会立即更新。刷新后getLocale()会返回新的语言intl.formatMessage也会用新的语言包。验证步骤启动项目npm run dev打开首页默认显示中文欢迎来到国际化演示浏览器标签页标题是首页。下拉框切到 English页面刷新标题变成Welcome to i18n Demo标签页标题变成Home。再切回中文确认能正常还原。如果标签页标题没变检查config.ts里路由的title字段是不是写成了menu.home这种 key而不是直接写中文。如果写死中文就不会跟着语言变。再验证一下 antd 组件。如果你用了 DatePicker切换语言后月份和星期应该跟着变。这就是antd: true的作用。如果没变确认 antd 的 locale 是否被正确注入。还有一个场景是模板字符串里的文案。比如 Modal 确认框import { Modal } from antd; import { useIntl } from umi; const Demo () { const intl useIntl(); const showConfirm () { Modal.confirm({ title: intl.formatMessage({ id: common.prompt }), content: intl.formatMessage({ id: common.noPermissions }), okText: intl.formatMessage({ id: common.confirm }), cancelText: intl.formatMessage({ id: common.cancel }), centered: true, }); }; return button onClick{showConfirm}open/button; };注意intl.formatMessage必须在函数组件或 Hook 里调用。如果你在组件外部定义了一个数组里面要用翻译不能直接调intl而是把intl作为参数传进去或者在组件内部用useMemo包一层。5. 本篇常见错排查401、local proxy failed、reading choices 等报错怎么解做国际化改造时报错主要集中在两类一类是插件配置问题一类是模型调用问题。我按真实遇到的报错来列。报错一Cannot read property formatMessage of undefined这个通常是因为useIntl没在组件里调用或者组件不是函数组件。intl.formatMessage只能在 Hook 函数组件里用。如果你在 class 组件里用需要改用injectIntl高阶组件或者把逻辑抽到函数组件里。报错二local proxy failed这个报错一般出现在你调用模型 API 时本地代理配置有问题。检查你的 Base URL 是不是写成了https://taotoken.net/api不要多加斜杠或者路径。如果你在脚本里用了代理工具确认代理地址和端口正确。另外有些环境变量比如HTTP_PROXY会干扰请求可以先 unset 掉再试。报错三401 Unauthorized这是 Key 的问题。检查 API Key 是否复制完整有没有多余空格。确认请求头里Authorization: Bearer 你的Key格式正确。如果 Key 过期或者额度用完也会返回 401去控制台确认一下。报错四reading choices这个报错说明你拿到的响应结构不对可能是模型返回了错误信息但你的代码直接去读choices字段。加一层判断const data await res.json(); if (!data.choices || !data.choices.length) { console.error(模型返回异常:, data); return; } const text data.choices[0].message.content;报错五OAuth相关错误如果你用的是某些需要 OAuth 授权的工具比如 Claude Code 或者 Codex 的 auth.json 配置报 OAuth 错误通常是 token 过期或者回调地址不对。这时候检查你的配置文件确认 Base URL、Key、Model ID 三件套都写全了。以 Codex 的auth.json为例需要包含{ baseUrl: https://taotoken.net/api, apiKey: 你的Key, model: 你的Model ID }如果是 Cline MCP 或者 CC Switch 这类工具同样要确认这三项。缺一个都会报错。报错六切换语言后部分文案没变这个多半是因为文案写死在代码里没走intl.formatMessage。全局搜一下中文字符串看看有没有漏掉的。另外有些第三方组件的文案不受 plugin-locale 控制需要单独引入对应的语言包。排查顺序建议先看控制台报错再看网络请求最后看配置文件。大部分问题都是配置写错或者 Key 不对。6. 语义一致 CTA把国际化流程接到稳定的模型调用上国际化改造做完之后你会发现真正费时间的不是配置而是文案的翻译和维护。每次产品加一个新页面就要同步更新zh-CN.ts和en-US.ts。如果团队里没人专门负责英文校对英文文案的质量就很难保证。这时候可以把翻译环节自动化。写一个脚本读取zh-CN.ts提取所有 value批量发给模型翻译再生成en-US.ts。这个过程需要一个稳定的 API 入口。TaoToken 的 API 地址是 https://taotoken.net/api 配合 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 拿到 Key就可以在脚本里调用。如果你对具体接入方式不熟可以看接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 里面有请求示例和参数说明。想先手动试一下模型效果用模型对话 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 贴几段中文看看英文返回质量。长期做国际化项目的团队建议用 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 把翻译、校对、生成 key 这些任务固定下来减少重复劳动。最后分享一个实用技巧在zh-CN.ts里给每个 key 加注释说明这个文案用在哪个页面、什么场景。这样模型翻译时能结合上下文英文更准确。比如export default { // 首页顶部大标题用于欢迎用户 home.title: 欢迎来到国际化演示, // 确认按钮用于弹窗 common.confirm: 确认, };注释不会被 umi 读取但能帮你和模型理解语境。这个习惯坚持下来后期维护成本会低很多。
返回列表