@codaco/app-i18n

中文文档
0.3.0发布于 2026/10/13MITTypeScriptES Module构建来源已验证近 30 天下载 3553

网络Canvas应用程序共享应用程序UI国际化:ICU消息目录,地语谈判,和React绑定.

中文使用文档
文档目录8 节
  1. 信件和目录
  2. 正在装入目录
  3. 东道国的责任
  4. Vite 构建
  5. 下一个带涡轮包的J
  6. 审定和生成指导
  7. 翻译来源
  8. 核查

应用程序 UI 本地化

@codaco/app-i18n 支持的网络国际化外观 Canvas应用铬. 议定书授权的内容、收集的数据和 持续识别器保留自己的语言和身份.

信件和目录

导入 defineMessages, (中文(简体) ), defineMessage, (中文(简体) ), createAppIntl及其类型 @codaco/app-i18n/messages。本条目在 React 服务器组件和 普通 JavaScript 语境 。 使用 useAppIntl 在客户端组件中; 它使 没有安装提供者时的英语默认值 .

给每个描述符一个稳定的名字空间,一个英文 defaultMessage,以及 向翻译解释背景的描述。 保持句子完整; 使用 ICU 复数/ 选择、 富文本标记和数字/ 日期参数而不是 加入已翻译的碎片.

import { defineMessages } from '@codaco/app-i18n/messages';
import { useAppIntl } from '@codaco/app-i18n/react';

const messages = defineMessages({
  selected: {
    id: 'example.records.selected',
    defaultMessage:
      '{count, plural, one {# record selected} other {# records selected}}',
    description: 'Selection count above the researcher records table.',
  },
});

function SelectedCount({ count }: { count: number }) {
  return useAppIntl().formatMessage(messages.selected, { count });
}

主机装入目录 common每个被消耗的包装 和自己的应用, 一次使用一个地方(参见 正在装入目录) (中文(简体) ). 每个地方 内 ecosystemLocales 每个共享目录中有完整的目录 软件包,但 en-GB,这是一个稀有的经过审查的英语功能。 联合国 src/locales/en.json 文件是生成的提取文物,从不运行时间 导入: 描述符默认提供英语运行时间倒计时。 保留 应用程序目录 src/locales/<canonical-BCP-47-tag>.json 页:1 构建时间汇编.

一个应用程序声明它实际支持的子集; 在其中添加一个地块 生态系统不需要其他应用程序来做广告. defineAppLocales 仅在明确启用时才添加诊断伪地. 不要坚持 作为生产选择的诊断选择.

使用 AppMessage 从 @codaco/app-i18n/react 用于队列对话框或土司 :

<AppMessage message={messages.selected} values={{ count }} />

节点即使排入队列也订阅到活动提供者. 当操作开始冻结旧语言时格式化为字符串. Fresco UI 对话框标题、描述、动作标签和 describeError 调用符接受这些节点.

对于现有的仅字符串错误/结果合同, createMessageError 从 @codaco/app-i18n/messages 保存一个简单文字描述符及其命名值 不捕捉活动区域。 它保留源默认并编译 ICU AST(重症监护室). Fresco UI 已有的字段/窗体出错渲染器解析这些消息 在语言切换时显示时间并保存服务器拒绝。 使用 AppErrorMessage 从 @codaco/app-i18n/react 用于存储的其他字符串错误,或 formatMessageError(error, intl) ?? error 在字符串渲染器中。 普通类 审定/诊断文本保持不变。 运输清单用途 { dependencies: { list: dependencyIds } },因此组合格式化为 读者的语言 而不是切换前的捕捉.

当整个信件包含单独拥有的被翻译的标签时,通过 { rule: { messageError: createMessageError(ruleDescriptor) } }清单项目 还接受这个清晰的包装。 普通的字符串总是字面数据, 即使它们恰好像一个编码错误。 此保存共享规则名称 和无名属性标签反应,而不重复其翻译.

正在装入目录

每个拥有目录的软件包都会导出装入器的地图:每个地方都有它 翻译,一个函数返回 import('./<tag>.json')。每种语言都是 因此,它自己的块,一个主机只下载它所下载的块。 联合国 没有装货机 也不需要.

软件包条目导出
@codaco/app-i18n@codaco/app-i18n/commoncommonCatalogLoaders
@codaco/fresco-ui@codaco/fresco-ui/localesfrescoUiCatalogLoaders
@codaco/interview@codaco/interview/localesinterviewCatalogLoaders
@codaco/network-exporters@codaco/network-exporters/localesnetworkExporterCatalogLoaders
@codaco/protocol-builder@codaco/protocol-builder/localesprotocolBuilderCatalogLoaders
@codaco/protocol-utilities@codaco/protocol-utilities/localesprotocolUtilitiesCatalogLoaders
@codaco/protocol-validation@codaco/protocol-validation/localesprotocolValidationCatalogLoaders

一个主机以同样的形状宣布自己的装载器,并传递它的一切 改为: createCatalogSource 从 @codaco/app-i18n/locales,按合并顺序排列: 常见的先是共享软件包,然后是应用程序. 后来加载器在共享上获胜 身份证.

import { commonCatalogLoaders } from '@codaco/app-i18n/common';
import {
  createCatalogSource,
  type CatalogLoaders,
} from '@codaco/app-i18n/locales';
import { frescoUiCatalogLoaders } from '@codaco/fresco-ui/locales';

const appCatalogLoaders: CatalogLoaders = {
  'es': () => import('./es.json'),
  'zh-Hans': () => import('./zh-Hans.json'),
};

export const catalogSource = createCatalogSource(
  commonCatalogLoaders,
  frescoUiCatalogLoaders,
  appCatalogLoaders,
);

来源一次合并并缓存一个地块 :

  • load(locale) 决定合并目录。 同时和重复的电话 共享一个请求,在负载失败后启动新请求.
  • attempt(locale) 返回该地块已有的负载,包括其 上次失败的尝试, 并且只有在没有尝试时才开始一次。 挂起这个 而不是说 load: 暂停使用 load 将开始一个新的 每次重试一次 都不要和解 A 类 load 尝试 在飞行中加入时作为尝试。 之前失败的 任何加入的尝试(如第一次渲染前的预装)都不可交付 因此,第一次尝试 之后仍然尝试新的.
  • peek(locale) 返回已装入的合并目录, 否则 undefined。没有软件包翻译的地块(英语,伪地块)是 总是准备好一个空目录.
  • subscribe(onLoad) 返回未订阅的选项.

useLocaleCatalog(source, locale, preloaded?) 从 @codaco/app-i18n/react 返回时 { locale, messages, failure } 给予 AppI18nProvider通过它 以结果代替请求的地块, 因为两者不同, 而开关 正在装入,当装入失败时:

import { AppI18nProvider, useLocaleCatalog } from '@codaco/app-i18n/react';
import type { ReactNode } from 'react';

import { appLocales } from './locales';
import { catalogSource } from './locales/catalogs';

export function I18n({
  locale,
  children,
}: {
  locale: string;
  children: ReactNode;
}) {
  const rendered = useLocaleCatalog(catalogSource, locale);
  return (
    <AppI18nProvider
      locale={rendered.locale}
      locales={appLocales}
      messages={rendered.messages}
      loadFailure={rendered.failure}
    >
      {children}
    </AppI18nProvider>
  );
}

钩子将当前语言保留在屏幕上,直到新语言装入, 然后在一次渲染中改变 所以开关从不通过英语或者 显示半翻译界面。 屏幕上什么都没有 也没有 要保留的语言, 因此第一个负载暂停: 使提供者处于 暂停边界, 或等待 source.load(locale) 在第一次变身之前 从不暂停.

永不停息界面的负载 。 开关留在当前 语言,第一个负载返回到英语,每个描述符 携带。 无论哪种方式,钩子都返回它无法装入的语言 failure,并不断尝试: 当设备回到网上, 在每次失败都加倍的等待之后 最多30秒 A 类 为页面寿命保留失败模块导入的浏览器, 如 Chrome 做,没有请求就回答失败的每一个重复,所以 在那里,语言只有在重新装入后才到达。 给 failure 通知提供者 作为 loadFailure,并告诉用户: useLocaleLoadFailure() 返回时 无法加载的语言的登记条目(locale)和 一个放在屏幕上shown),与 error,以及 LocaleLoadFailureToast 从 @codaco/fresco-ui 把它当作一个祝酒词,直到它被解职或 语言到达.

服务器主机加载请求的目录,格式,并发送相同的 向客户端发送信息作为道具。 把他们当成钩子 preloaded 参数 在不下载的情况下制作该语言的水合物和水合物,持续时间最长 preloaded.locale 匹配 locale数字 :

// On the server, per request:
const messages = await catalogSource.load(locale);
const intl = createAppIntl({ locale, messages });

// In the client provider, with `messages` received as a prop:
const rendered = useLocaleCatalog(catalogSource, locale, { locale, messages });

在不需要资源的地方, 如一次性服务器, 一个故事书 装潢或测试, loadCatalog(locale, ...loaders) 从 @codaco/app-i18n/locales 装入并合并一个单一区域 :

import { commonCatalogLoaders } from '@codaco/app-i18n/common';
import { loadCatalog } from '@codaco/app-i18n/locales';
import { frescoUiCatalogLoaders } from '@codaco/fresco-ui/locales';

const messages = await loadCatalog(
  'es',
  commonCatalogLoaders,
  frescoUiCatalogLoaders,
);

装填器不带电源就导入JSON import 属性, 所以目录负载 只能通过捆绑机;节点自己的无害环境管理装载机无法读取. 软件包或应用程序 拥有目录的人声称 src/locales/<tag>.json 有一个 装入器装入它,没有装入器在缺少的文件上点出 checkCatalogLoaders(localesDir, loaders) 从 @codaco/app-i18n/catalog-guards。 。 。 . 它解决了一系列问题,当装入器正常时会空出.

东道国的责任

挂载 AppI18nProvider 与活动区域、所支持的注册和 locale 来自目录来源的消息 。 内容 onLocaleChange 召回代表 (一) 东道方的持久性; null 意思是自动谈判. resolveAppLocale 手柄卡通化, 最适合的浏览器匹配, 和明确的英文倒置 。 中国的请求 由脚本匹配,所以 zh-TW, (中文(简体) ), zh-HK 财务报告和审定财务报表 zh-MO 选择 zh-Hant 财务报告和审定财务报表 zh, (中文(简体) ), zh-CN 财务报告和审定财务报表 zh-SG 选择 zh-Hans,即使一个通用 zh 随行 浏览器列表中的区域标记 。 HTTP 主机可以获取所请求的标记 使用 parseAcceptLanguage 从根 @codaco/protocol-validation 输出.

外部提供者管理文档 lang 财务报告和审定财务报表 dir嵌入式参与者 采访或预览有一个独立的提供者,其地址是: manageDocument={false} 及其自身的要素 lang 财务报告和审定财务报表 dir。保留当前协议 runtime语言独立于研究者偏好.

服务器主机先解决请求的账户/ 设备/ 浏览器偏好 渲染,然后将初始化序列化给客户端. 创建每个服务器 用于与 createAppIntl,通过目录 source.load(locale); 不将特定请求的本地状态放入 模块全局或跨用户缓存。 使用相同的明示 timeZone 两者 用于确定日期/时间水分的服务器格式和客户端提供者.

Vite 构建

地点 appI18n() 从 @codaco/app-i18n/vite 在框架插件之前。 这个 编译源默认和导入到 ICU 的本地目录并删除 生产应用程序中的运行时间解析器构建。 一个出版的软件包 拥有描述符/目录使用 appI18n({ build: 'library' }) 来编译它们 并让其消费者选择解析器.

下一个带涡轮包的J

使用 @codaco/app-i18n/next-loader 用于源默认和源语言目录. 共享加载器应用与 Vite 相同的编译器并保存客户端 指令。 。 。 源码规则保留了原扩展名, 所以下个仍然 进行其正常的TypeScript/JSX变换;只有JSON规则出JavaScript.

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  turbopack: {
    rules: {
      '*.{js,jsx,ts,tsx}': {
        condition: { not: 'foreign' },
        loaders: ['@codaco/app-i18n/next-loader'],
      },
      '**/src/locales/*.json': {
        condition: { not: 'foreign' },
        loaders: ['@codaco/app-i18n/next-loader'],
        as: '*.js',
      },
    },
    resolveAlias: {
      ...(process.env.NODE_ENV === 'production'
        ? {
            '@formatjs/icu-messageformat-parser':
              '@formatjs/icu-messageformat-parser/no-parser.js',
          }
        : {}),
    },
  },
};

export default nextConfig;

工作空间包导出源, 因此规则也会编译其描述符 和目录。 已发布软件包导出预编译 dist 文物和必须 在库建过程中编译自己的消息. 一个非目录 JSON 文件 仍然是普通数据。 不另名运行时解析器, 除非每个来源 编译默认和运行时间目录.

审定和生成指导

没有框架的工人/CLI诊断方法保持不变。 研究员 主机可以通过自有软件包选择本地化的演示文稿 :

  • @codaco/protocol-validation/messages: 协议文件错误描述符, 验证规则标签、可诉矛盾摘要和 formatMigrationNotes(version, notes, intl) 用于移民审批指南. 已知的迁移版本, 翻译每个完整的 Markdown 句号同时 保存列表结构和字面协议默认;未知版本 保留他们提供的笔记。 核心移徙说明仍是英文.
  • @codaco/protocol-utilities/messages: 选择生成冲突指导 (d) 原有技术诊断.
  • @codaco/network-exporters/messages: 选择导出进度描述符 由稳定的事件阶段标识.
  • @codaco/protocol-builder: 本地化的舞台界面显示名称, 保存 持续的协议命名独立于活动区域.

每个软件包通过其翻译提供翻译 ./locales 输出。 这个 验证/用户/出口商中的信息和地址条目可选 @codaco/app-i18n 端点;其现有的引擎切入点不获取 反应依赖。 选择本地化演示文稿的主机安装端点和 添加软件包的目录加载器( 列在 正在装入目录他们的目录来源.

翻译来源

更改英文句子使其翻译无效。 每个本地目录 有一份英文的忠实记录 它的录入来自一个兄弟 src/locales/<tag>.source.json和目录的守卫失败 当一个记录 句子已经不再匹配今天的 en.json。 。 。 .

没有它,一个重写英文字符串 留下每一个翻译说老 与每一个其他的守卫 仍然绿色:目录是完整的, ICU 参数仍然匹配,无一是空白的,错误的拷贝在屏幕上。 这个 而非假设 协议在英语更改后被下载,以表示否 文件是写出来的.

因此,当翻译背后的英语变化时:

  1. pnpm --filter <pkg> i18n:extract 重新生成 en.json和警卫 以 ID 开始失败, 它从英文译出 它现在说, 和翻译本身.
  2. 从这三句里决定 大多数英语编辑是 社论——大写,逗号,同义词——译名还原 说对了 有些改变意义,翻译必须 在它回到读者面前之前重写.
  3. pnpm --filter <pkg> i18n:stamp 重写记录并打印每对 它接受了。 阅读该报告,并在重新翻译的同时予以执行; 副车厢是可审查的被接受的记录.

从磁盘中读取这些文件; 从不导入 。 所以英国人才会这样 复制出捆绑, 名称会备份它: 地方标记不能包含 点, 因此扫描本地目录的构建步骤不会出错 es.source.json 为目录.

只有 defaultMessage 记录,而不是 description。描述是 其编辑原因并不改变 将两人连成一对 将守卫解雇 澄清并训练人们不读就重新加印 习惯会让这个警卫一文不值.

核查

运行每个所有者 i18n:extract 脚本并输入生成的英文目录 . 编目警卫检查新鲜度 身份证 翻译描述 完整 西班牙语、英国英语、有效伊斯兰法院联盟、占位符/丰富文本等同 每一个忠实的目录都有一个装入器,每个翻译 仍然记录着它用英文做的. 此外,还审计了JSX以外的表面和复制品: 目录无法找到从未被提取的字符串 。 锻炼生产 构建、活的地盘变化、主机偏好持续以及独立 审查翻译的含义和布局.

版本与发布记录

@codaco/app-i18n 共发布 3 个版本,首次发布于 2026/09/10;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/10/1327 天前
0.2.02026/09/291 个月前
0.1.02026/09/102 个月前

关于 @codaco/app-i18n 的常见问题

@codaco/app-i18n 是什么?

网络Canvas应用程序共享应用程序UI国际化:ICU消息目录,地语谈判,和React绑定.

如何安装 @codaco/app-i18n?

在项目目录运行 npm install @codaco/app-i18n,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.3.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@codaco/app-i18n 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@codaco/app-i18n 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@codaco/app-i18n 可以商用吗?

@codaco/app-i18n 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@codaco/app-i18n 的下载量有多少?

根据 npm 官方下载统计,@codaco/app-i18n 在 2026/10/10 – 2026/11/08 这 30 天内被下载 3,553 次,日均约 118 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@codaco/app-i18n 还在维护吗?

最新版本 0.3.0 发布于 2026/10/13(27 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/09/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。