Skip to content
文档设计原则

设计原则

本页深入介绍了 next-intl 所基于的设计原则。

虽然使用本页内容并非在项目中高效使用该库的必读内容,但它能帮助你更好地理解库背后的理念,并助于你评估 next-intl 是否适合你的项目。

本页同时链接了一些计划中的改进,旨在作为未来期待的透明参考。

全面性

国际化显然需要你的代码库具备灵活性。然而,即使是实现单一语言的完整支持,也已经是一个挑战。

使用动态文本标签是国际化中最明显的方面,但良好支持一门语言还包括许多其他方面:

  1. 复数规则:比如英语只有两种复数形式(单数和复数),而其他语言最多可有六种不同的形式。
  2. 日期和时间格式:不同语言对日期和时间的格式有不同习惯。甚至年份的显示也会因国家而异,例如泰国采用的佛历比公历提前543年。
  3. 数字格式:数字的格式化规则在语言之间不同。例如,英语和德语中千位分隔符和小数点符号是互换的。
  4. 列表格式:像“HTML、CSS 和 JavaScript”这样的列表格式,不仅仅是字符串的简单拼接,还需要使用语言特定的连接词和标点符号。
  5. 文本方向:大多数语言是从左到右书写,但阿拉伯语等语言是从右到左书写,需要镜像布局。

此外,还有典型的应用问题,例如:

  1. 富文本格式:许多应用需要支持某种富文本格式,例如在文本标签中嵌入链接(“在富文本文档中了解更多。”)。
  2. 时区:日期展示需要服务器端和客户端对时区的统一处理,甚至可能基于用户偏好进行定制。
  3. 相对时间格式:展示“5分钟前”或“2小时后”等相对时间需要特别注意格式,还需要一个统一的当前时间参考值。还可能需要定时更新显示的时间。
  4. 本地化 URL:URL 应该本地化以匹配用户的语言偏好(如英语用 /en/about-us,西班牙语用 /es/sobre-nosotros)。实现上需要将请求映射到正确页面,并提供简化的 API 让开发者能以与语言无关的方式链接页面。
  5. 语言协商:应基于浏览器设置检测用户语言偏好,同时支持手动配置——即使用户未登录。
  6. SEO:搜索引擎需要了解页面的本地化版本,以便向用户呈现最佳匹配内容。
  7. 国家特性:如果你在多个国家提供服务或产品,可能需要考虑不同的货币和计量单位。
  8. 环境差异:你的组件可能在服务器端、客户端或两者执行。为了实现一致渲染,需要确保整个应用统一访问诸如用户区域设置、时区以及当前时间参考等属性。

考虑上述内容,你可能已经能体会到国际化问题的庞大和不同部分之间的紧密联系。

next-intl 采取全面的国际化方法,推动你遵循处理语言和国家特定习俗的最佳实践,从而让你更专注于打造应用的核心独特之处。

计划中的改进

易用性

本库大胆宣称,当你实现国际化时,应用代码反而会变得更简单而非复杂。

如果你考虑国际化的全局视角,显而易见大部分组件都会以某种方式涉及国际化。鉴于此,next-intl优先提供便利的 API,确保你在开发时高效且可控。作为开发者,你应只需专注于解决实际问题,国际化则作为副产品无缝集成其中。

一旦完成国际化设置,添加新语言在最简单的情况下,仅需添加包含翻译的 JSON 文件——其他由 next-intl 自动处理。

计划中的改进

基于标准

随着ECMAScript 国际化 API 的引入,近年来 JavaScript 在日期、时间、数字、列表和复数格式化方面变得非常强大。next-intl 构建于此 API 之上,提供符合开发习惯的接口,同时结合应用的具体配置需求。

在文本格式化方面,next-intl 基于Unicode 国际组件(ICU)——ICU 是一个成熟且广泛使用的国际化标准,得到许多编程语言和框架支持。next-intl 使用 ICU 消息语法定义文本标签,能简明且易读地表达复杂格式需求,比如变量插值和复数规则,且对译者等非开发者友好。

基于标准,next-intl 确保你的国际化代码具备未来兼容性,并令已有国际化经验的开发者感到熟悉。此外,依赖标准也保证了 next-intl 可很好地与诸如 Crowdin 等翻译管理系统集成。

next-intl 使用嵌套式结构来组织消息,允许以无冗余的方式表达消息层级。通过仅支持单一结构,我们能提供基于此假设的高级功能,如消息的类型安全。若你使用不同结构风格,可考虑迁移到嵌套式结构(详见消息结构文档中的“我可以用其他结构风格吗?”部分)。

随着标准的变化,next-intl 也会跟进 ECMAScript 标准的最新发展(例如 TemporalIntl.MessageFormat)。

计划中的改进

兼容性

虽然 next-intl 设计为以全面方式处理国际化,但国际化往往需要与其他工具和服务集成,允许你采用最合适的工具并与非开发者协作。

典型应用可能需要以下集成:

翻译管理系统(TMS)

通常用于管理翻译和与译者协作。如 Crowdin 提供丰富功能,支持译者在基于网页的界面处理翻译,并以多种机制同步翻译与应用。

next-intl 与此类服务集成良好,因它使用广泛支持的 ICU 消息语法定义文本标签。推荐将消息存储为按语言划分的 JSON 文件,这是一种流行格式,便于导入进 TMS。虽然推荐至少将默认语言的消息本地保存(例如支持类型安全消息),但你也可以动态加载消息,比如从 TMS 提供的 CDN。

内容管理系统(CMS)

若你的应用使用 CMS 内容,可与 next-intl 配合使用。例如,你可能希望在 CMS 管理博客文章或营销文案,同时用 next-intl 管理 UI 标签。

CMS 通常支持多语言内容定义,通过 REST API 获取内容。利用 next-intl 返回的协商后的应用语言(通过 getLocale),并将其传入 CMS API 请求,可获取用户偏好语言的内容。

后端数据

类似 CMS,你可能有后端服务或数据库中的数据需基于用户语言和国家查询。例如,根据国家显示不同价格和货币,或展示本地化的产品名称。通过使用 next-intl 协商的应用语言发起后端请求,可以确保本地化贯穿应用各处。

其他库

Next.js 拥有丰富的生态库,可与 next-intl 配合使用,比如处理认证。通过提供常见集成的文档和示例,next-intl 确保你在与其他库集成时体验顺畅无阻。

计划中的改进

性能优化

next-intl 从设计之初就面向高流量网站,旨在提供快速且可靠的用户体验,并在复杂电商页面中已证明其卓越的核心网络性能指标(Core Web Vitals)。

为实现此目标,next-intl 当前主要依赖以下技术:

  1. RSC 优先:深度整合 React 服务端组件,将工作转移至构建步骤或高性能服务器,从而减少客户端运行时负担。
  2. 消息拆分:按语言划分消息,且可按服务器、客户端及组件拆分,减少传给客户端的消息体积。对支持多语言且消息量大的应用尤为关键。
  3. 缓存:消息解析以及 Intl 构造器实例化均在应用中缓存,降低计算量。
  4. 捷径:比缓存重复工作结果更好的是避免重复计算(例如,检测不需解析的纯文本消息)。

计划中的改进

专为 Next.js 设计

Next.js 提供了许多功能,但同时也带来许多必须谨慎处理的细节,以实现可靠的国际化集成。顾名思义,next-intl 主要设计与 Next.js 深度协同。它不追求一刀切,而是根据需要深度集成 Next.js,持续关注 Next.js 生态的最新发展。

尽管如此,next-intl 核心库为 Next.js 无关,适用于任意 React 应用,甚至纯 JavaScript 环境:use-intl。该核心库包含 next-intl 大多数特性,但缺乏 Next.js 专属的集成如路由 API。其目标是在生态其他部分(如 React Native)复用熟悉 API,且若将来你觉得 Next.js 不再适合项目,也提供简明的迁移路径

便于迁移

我们都经历过技术演进,有时也需要跟进变化。next-intl 设计为你的代码库友好公民,方便在必要时迁移替换某些堆栈部分。

若你觉得 Next.js 或 next-intl 不再适合你的项目,你有以下多个选项:

  1. 放弃 Next.js:若决定迁移离开 Next.js,可继续在任何 React 应用中使用核心库 use-intl,例如让你能复用已有组件于 React Router 应用中。
  2. 放弃 next-intl:若觉得 next-intl 不符合需求,需修改引用库的应用代码,但仍能复用你的基于标准的 ICU 消息,并可用直接调用ECMAScript 国际化 API 替代格式化 API。

我们不会阻止你,但乐意继续做朋友。

当然,我们会尽全力让 next-intl 成为你项目的好帮手。如果你觉得哪里不尽如人意或有改进建议,请随时在问题追踪区反馈,我们将尽力帮你解决。


哇,这篇文章真长。你真的全读完了吗?next-intl 诞生于对国际化的浓厚兴趣与热情,看来我们志同道合!我们总想知道 next-intl 给你的体验如何,如有反馈或疑问,欢迎随时联系我们