MessageFormat 2 · 给人看的消息怎么写
把「You have 3 new messages」翻成几十种语言,要应付复数(英语 2 档、波兰语 4 档、阿拉伯语 6 档)、语序、性别一致、还要在句中加粗 / 加链接。MessageFormat 2(MF2)是 Unicode 给这个老问题的新标准:一套既能被译者读懂、又能跨实现(ICU4C / ICU4J / JS)复用的消息语法,并正进入 ECMA-402 的 Intl.MessageFormat 提案。
本系列按官方文档的脉络铺开:先看消息的语法构成,再到内置函数、选择与变体、声明、标记,最后是 JavaScript 里的 messageformat 包 API 与错误处理。每页都能改消息源、传值、换 locale,实时看真实引擎(打包进来的 messageformat v4)的输出。
为什么不能直接拼字符串
从拼接、printf 到 ICU MessageFormat 1 的演进,说明 MF2 为何要重做一套语法。
一条消息长什么样
simple message 的占位符、转义与字面量写法,以及变量引用与嵌套属性取值。
函数:给值挑一种本地化形式
内置与 DRAFT 函数的操作数与选项,以及同一个值在各 locale 下的形态差异。
选择:同一条消息的多个版本
.match 按复数类别或任意选择子挑变体,多选择变量时最左列优先;命中结果随 locale 而变。
声明:给输入注解、给中间值起名
.input 给外部变量绑定默认注解并兼作选择子,.local 命名中间结果复用;出现声明即 complex message。
标记:让译者也能安全地加粗、加链接
开标记、闭标记与自闭合标记只在 formatToParts 里出现,由宿主决定渲染成什么元素。
messageformat 包:在 JS 里跑 MF2
messageformat 包的构造选项、format 与 formatToParts 两个出口,以及数据模型层的解析、回写与校验工具。
错误与回退:坏消息也要给个像样的输出
语法、数据模型、解析与运行四个阶段的错误分类,以及各自的回退输出与方向隔离符的处理。
messageformat 包(v4)。本系列的 demo 都跑这个真实引擎;日期 / 货币等 DRAFT 函数已替你用 DraftFunctions 注册好,故可直接体验。相关链接
- MessageFormat 2 · 官方站点 messageformat.unicode.org 本系列对照的官方文档:语法参考(Functions / Literals / Variables / Markup / Matchers / Patterns / Errors)、各语言集成指南,以及一个在线 Playground。
- UTS #35 Part 9 · MessageFormat 规范本体 unicode.org LDML 的 MessageFormat 章节:消息语法的 ABNF、数据模型、解析 / 解析 / 格式化算法、默认函数注册表(含 REQUIRED / DRAFT 分档)与错误定义的权威来源。
-
messageformat · JS 实现 (v4)
github.com
本系列 demo 打包的引擎:
MessageFormat类、messageformat/functions的DefaultFunctions/DraftFunctions、数据模型工具与messageformat/cst具体语法树。 -
TC39 · Intl.MessageFormat 提案
tc39.es
把 MF2 引入 ECMA-402、成为浏览器内置
Intl.MessageFormat的提案。落地后,本系列的 JS 用法将不再需要安装包。 -
MDN · Intl 命名空间
developer.mozilla.org
Intl国际化对象总览:NumberFormat/DateTimeFormat/PluralRules等现有构造器。MF2 的:number/:date等内置函数即建立在这套底层格式化能力之上;Intl.MessageFormat提案落地后也将归入此页。
解析内核与二进制 AST
- intlify · Binary AST Snapshot v0.1 Writer + Decoder github.com intlify 解析器 crate 为 MF2 解析树实现的二进制快照格式:字符串 interning(FNV-1a)、8 字节对齐的定长记录、zero-copy 遍历,把「解析后的 AST」序列化成可校验、可直接按偏移读取的字节流,跳过重复解析。
- TC39 · JavaScript Binary AST (BinAST) 提案 github.com 把 JavaScript 源码预先解析成二进制 AST 再发给浏览器、跳过解析以加快启动的标准化尝试(现已搁置)。与上面 MF2 快照同源的思路:用紧凑二进制布局换取免重复 parse 的加载性能。
- V8 · Code caching for JavaScript developers v8.dev V8 缓存编译产物(bytecode / code cache)以复用、规避重复 parse 与 compile 的工程方案,是 BinAST 之外解决「解析慢」问题的另一条主流路径。