--- createdAt: 2026-09-16 updatedAt: 2026-09-16 title: "如何在 2026 年选择合适的 React i18n 库" description: "React 国际化选型指南。在对比 react-i18next、react-intl、Lingui、use-intl、Paraglide 和 Intlayer 之前需要回答的关键问题,以及各方案在 bundle size、类型支持和维护成本方面的权衡。" keywords: - React i18n - React 国际化 - react-i18next - react-intl - Lingui - use-intl - Paraglide - Intlayer - i18n 库对比 slugs: - blog - how-to-pick-react-i18n-library author: aymericzip --- # 如何选择合适的 React i18n 库 React 本身并没有提供内置的 i18n 原语。你在项目第一天选择的库,将决定翻译如何存储、如何打包进 bundle,以及未来几年需要承担多少维护工作。大多数团队通常根据流行度来选型,随后在翻译键达到 2,000 个时才发现各种妥协与限制。 本指南采用另一种思路:先回答关于你项目的几个核心问题,然后将答案映射到最契合的库。本文重点关注纯 React 生态(Vite、React Router、TanStack Start)。Next.js 有其专属的约束,已在 [Next.js 对比文章](https://github.com/aymericzip/intlayer/blob/main/docs/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md) 中详细介绍。 ![React i18n 库生态系统](https://github.com/aymericzip/intlayer/blob/main/docs/assets/cloud_i18n_logo.webp?raw=true) ## 目录 ## 在对比各库之前需要回答的 6 个问题 如果不清楚哪些指标对你最重要,功能对比表格就毫无意义。请先梳理以下问题: 1. **应用采用何种渲染方式?** 纯 SPA、带 hydration 的 SSR,还是 React Server Components。基于 Context 的 Hook 在 SPA 中处处适用;但在 RSC 中,Hook 会强制要求渲染文本的每个组件都加上 `"use client"`,因此你还需要服务端 API。 2. **谁来编写翻译?** 开发者、使用 TMS 的内部团队、交付 ICU 文件的翻译公司,还是 AI 自动化流程。这比任何 API 细节都更能决定翻译目录的格式。 3. **有多少个语言环境和页面?** 2 个语言环境和 5 个页面完全可以一次性打包所有内容;10 个语言环境和 50 个路由则无法承受,加载策略将成为核心成本。 4. **翻译键是否需要强类型约束?** 在所有基于键的库中,`t("checkout.totl")` 中的拼写错误都能通过编译,除非你手动配置类型。评估团队是否能接受这一点。 5. **文案包含哪些内容?** 纯文本、复数形式,还是中间嵌入 `` 的复杂句子。富文本内容往往是多数 API 变得臃肿的地方。 6. **项目的生命周期有多长?** 一个 3 个月的原型项目和一个维护 5 年的产品,对构建工具链的需求完全不同。 写下你的答案,后文的所有分析都将围绕它们展开。 ## 一图看懂技术演进版图 十五年的 JavaScript i18n 发展史可以归纳为四波架构浪潮,而你所对比的 React 库正来自于不同的阶段。 ![JavaScript i18n 库发展史](https://github.com/aymericzip/intlayer/blob/main/docs/assets/history_i18n.webp?raw=true) 在内存中加载 JSON 目录,运行时查找 `t("a.b")`,并在浏览器中解析 ICU 或自定义语法。生态最庞大,运行时最重,类型支持为 opt-in(可选配置)。 在构建时提取文案并编译为紧凑目录,提供类型化参数。通过增加额外的构建步骤(`extract`、`compile`)换取更小的 bundle 体积。 围绕 SSR 和 Server Components 设计。在服务端完成渲染,客户端仅 hydrate 必需的内容。本质上仍然基于键且集中管理。 文案被编译为支持 tree-shaking 的函数或按组件划分的字典。类型自动生成,缺失翻译直接中断构建,并通过 CLI 执行 AI 翻译。 [JavaScript i18n 历史](https://github.com/aymericzip/intlayer/blob/main/docs/blog/zh/history_of_i18n.md) 详细探讨了每一波浪潮是如何解决前一波痛点的。 ## 最关键的抉择:内容存放在哪里以及何时加载 所有 React i18n 库都具备相似的结构:一个 store、一个 provider、一个 hook。Provider 接收的任何内容最终都会进入客户端 bundle 或 hydration payload 中。因此,两个根本性的架构选择是: - **集中式还是局部作用域内容:** 整个应用共用一个 `en.json`,还是每个组件(或每个 namespace)独立声明。 - **静态导入还是动态导入:** 启动时打包所有内容,还是按需获取当前语言环境与路由的内容。 下图估算了包含 1 到 10 个页面、翻译成 1 到 10 个语言环境、每页约 30 KB 文本的理论应用 payload: ![不同架构下的理论内容泄漏](https://github.com/aymericzip/intlayer/blob/main/docs/assets/theorical_content_leakage.webp?raw=true) 采用静态导入的集中式内容会随着两个维度同时膨胀:10 个页面乘以 10 个语言环境,意味着每个页面都要加载 300 KB 的文本。动态导入消除了语言维度的膨胀,组件级作用域消除了页面维度的膨胀,只有两者结合才能让体积保持平稳。 这不仅是库的特性,更关乎工程规范。`react-i18next` 可以通过 namespace 和 lazy backend 实现作用域划分,`use-intl` 也可以按路由拆分。但工具链本身并不会强制执行,一个通用的 `