40 lines
2.4 KiB
Markdown
40 lines
2.4 KiB
Markdown
# 浏览器运行时
|
||
|
||
`runtime.mjs` 是可独立导入的 ES module,`runtime.d.mts` 提供类型。需要支持 ES modules、BigInt、TextEncoder 和 structuredClone 的现代浏览器;Node.js 22 用于本仓库验证。复数规则来自导出包,与 Go 共用固定 CLDR 数据,不调用浏览器自己的 Intl.PluralRules。语言选择使用包中 `locales` 的精确标识,不由浏览器再次改写别名或推断回退链。
|
||
|
||
```js
|
||
import { createLanguageController, fetchPack } from './runtime.mjs';
|
||
|
||
const urls = { en: '/locales/en.json', 'zh-Hans': '/locales/zh-Hans.json' };
|
||
const language = createLanguageController(
|
||
await fetchPack(urls.en),
|
||
locale => fetchPack(urls[locale])
|
||
);
|
||
|
||
await language.setLanguage('zh-Hans');
|
||
const text = language.current.t('ui', 'greeting', { name: 'Alex' });
|
||
```
|
||
|
||
`current.render` 额外返回实际语言和 fallback 标记。`setLanguage` 成功提交返回 true;被更新选择取代返回 false;最新加载失败抛错并保留 current。甚至“切回当前语言”也会取消旧请求的提交资格。未知语言、错误语言包、参数 schema 或启用语言集合变化都不能提交。
|
||
|
||
`fetchPack` 检查 HTTP 状态和 4 MiB 限额,支持 AbortSignal 和自定义 fetch。加载资源、鉴权、缓存策略与 URL 映射由调用者决定。它只返回 JSON 数据,`createLocalizer` / controller 负责完整资源检查。
|
||
|
||
`overlayPack(pack, documents)` 显式覆盖已导出键的完整消息并重新校验,不修改输入,不允许改变参数契约。例如替换品牌标题;覆写源消息时保留原 params。业务可在 loader 返回之前应用 overrides。
|
||
|
||
```ts
|
||
import type { Translate } from './messages.generated';
|
||
const t: Translate = language.current.t;
|
||
// t('ui', 'greeting', { name: 'Alex' })
|
||
```
|
||
|
||
应用需要在切换成功后重新取得 current.t。视图使用 textContent 或框架的文本绑定,动态参数不递归解析、不作为 HTML 执行。金额格式化、RTL 布局、表单、路由、业务提交和偏好持久化属于应用;运行时不重建页面或重新发业务请求。
|
||
|
||
完整表单示例:[examples/i18n](../../examples/i18n/README.md)。验证:
|
||
|
||
```sh
|
||
node --test i18n/browser/runtime.test.mjs
|
||
go test ./i18n -run TestBrowserConformance
|
||
# PATH 中提供 tsc 时,验证导出类型与实际 runtime 声明及错误参数诊断。
|
||
go test ./i18n -run TestTypeScriptConsumer -v
|
||
```
|