← MessageFormat 2 · 给人看的消息怎么写 / messageformat 包:在 JS 里跑 MF2 待审核 7 / 8
api · JavaScript 包

messageformat 包:在 JS 里跑 MF2

MF2 目前不是浏览器内置 API(ECMA-402 的 Intl.MessageFormat 仍在提案阶段),在 JS 里用它要装 messageformat 包(v4,实现 LDML 48 与 TC39 提案)。本页这些 demo 的输出全部由打包进来的真实引擎实时产生。核心就一个 MessageFormat 类,外加一组数据模型工具函数。

1 · 安装与构造

日期 / 货币等 DRAFT 函数不在默认注册表,需经 functions 选项传 DraftFunctions 开启:

构造一个 formatter

import { MessageFormat } from 'messageformat';
import { DraftFunctions } from 'messageformat/functions';

const mf = new MessageFormat(
  'en',                                  // locales: string | string[] | undefined
  'Hello {$name}, today is {$d :date length=long}',
  { functions: DraftFunctions }          // options (可选)
);
构造选项 作用
functions 注册自定义 / DRAFT 函数,扩展默认注册表
bidiIsolation 'default'(默认,隔离插值)/ 'none'(不加隔离符)
dir 显式指定基准方向 'ltr' / 'rtl' / 'auto',默认按 locale 推断
localeMatcher 多 locale 时的协商算法 'best fit' / 'lookup'

2 · format()formatToParts()

构造好后,format(values?, onError?) 出字符串;formatToParts(values?, onError?) 出零件数组(拿来做富文本 / 拆分样式 / 处理 markup)。改下面的源与值,两个出口同时看:

第二参 onError 回调捕获运行期错误;不传时引擎默认把错误以 console.warn 打出,并仍返回 回退结果(不会中断整条消息)。本系列的封装把错误收集起来显示在红框里。注意 v4 的 MessageFormat 没有 resolvedOptions()

3 · 自定义函数

functions 选项里登记的每个函数签名是 (ctx, options, operand) => MessageValue。返回的 MessageValue 至少要能 toString()(供 format)与 toParts()(供 formatToParts);若还想参与 .match,再实现 selectKey(keys)。下例加一个 :uppercase:

自定义 :uppercase 函数

const uppercase = (ctx, options, operand) => {
  const out = String(operand ?? '').toUpperCase();
  return {
    type: 'string',
    toString: () => out,
    toParts: () => [{ type: 'string', value: out }]
  };
};

const mf = new MessageFormat('en', 'WARNING: {$msg :uppercase}',
  { functions: { uppercase } });
mf.format({ msg: 'disk full' });

4 · 数据模型:parseMessage / stringifyMessage / validate

除了「源串 → 输出」,包还暴露数据模型层:parseMessage(src) 把消息解析成结构化对象树(可程序化改写、做 lint / 提取),stringifyMessage(model) 反向序列化,validate(model) 返回消息用到的 functionsvariables 集合。写一条消息看它的树:

包里还有一组类型守卫(isExpression / isLiteral / isMarkup / isSelectMessage …)与遍历器 visit(model, visitors),配合数据模型做静态分析 / 转换。子路径 messageformat/cst 还提供更底层的具体语法树(保留空白 / 注释,适合写编辑器、格式化器)。