On this page

Node.js 拥有许多功能,使编写国际化程序变得更加容易。其中一些功能包括:

Node.js 和底层的 V8 引擎使用 International Components for Unicode (ICU) 在原生 C/C++ 代码中实现这些功能。Node.js 默认提供完整的 ICU 数据集。但是,由于 ICU 数据文件的大小,在构建或运行 Node.js 时提供了几个选项来自定义 ICU 数据集。

为了控制 ICU 在 Node.js 中的使用方式,编译期间有四个 configure 选项可用。有关如何编译 Node.js 的更多详细信息记录在 BUILDING.md 中。

  • --with-intl=none/--without-intl
  • --with-intl=system-icu
  • --with-intl=small-icu
  • --with-intl=full-icu(默认)

每个 configure 选项可用的 Node.js 和 JavaScript 功能概述:

功能nonesystem-icusmall-icufull-icu
String.prototype.normalize()无(函数为空操作)完整完整完整
String.prototype.to*Case()完整完整完整完整
Intl无(对象不存在)部分/完整(取决于操作系统)部分(仅英语)完整
String.prototype.localeCompare()部分(非区域感知)完整完整完整
String.prototype.toLocale*Case()部分(非区域感知)完整完整完整
Number.prototype.toLocaleString()部分(非区域感知)部分/完整(取决于操作系统)部分(仅英语)完整
Date.prototype.toLocale*String()部分(非区域感知)部分/完整(取决于操作系统)部分(仅英语)完整
旧版 URL 解析器部分(无 IDN 支持)完整完整完整
WHATWG URL 解析器部分(无 IDN 支持)完整完整完整
require('node:buffer').transcode()无(函数不存在)完整完整完整
REPL部分(行编辑不准确)完整完整完整
require('node:util').TextDecoder部分(支持基本编码)部分/完整(取决于操作系统)部分(仅 Unicode)完整
RegExp Unicode 属性转义无(无效的 RegExp 错误)完整完整完整

"(非区域感知)" 标识表示该函数执行的操作与其非 Locale 版本的操作相同(如果存在的话)。例如,在 none 模式下,Date.prototype.toLocaleString() 的操作与 Date.prototype.toString() 的操作相同。

仅需要 ICU 库本身的功能,如 String.prototype.normalize()WHATWG URL 解析器,在 system-icu 下得到完全支持。需要 ICU 区域数据的功能,如 Intl.DateTimeFormat,可能得到完全或部分支持,这取决于系统上安装的 ICU 数据的完整性。

仅需要 ICU 库本身的功能,如 String.prototype.normalize()WHATWG URL 解析器,在 small-icu 下得到完全支持。需要 ICU 区域数据的功能,如 Intl.DateTimeFormat,通常仅适用于英语区域设置:

const january = new Date(9e8);
const english = new Intl.DateTimeFormat('en', { month: 'long' });
const spanish = new Intl.DateTimeFormat('es', { month: 'long' });

console.log(english.format(january));
// 输出 "January"
console.log(spanish.format(january));
// 在 small-icu 上输出 "M01" 或 "January",取决于用户的默认区域设置
// 应该输出 "enero"

此模式在功能和二进制大小之间提供了平衡。

如果使用了 small-icu 选项,仍然可以在运行时提供额外的区域数据,以便 JavaScript 方法适用于所有 ICU 区域设置。假设数据文件存储在 /runtime/directory/with/dat/file,可以通过以下方式使其对 ICU 可用:

  • --with-icu-default-data-dir configure 选项:

    这仅将默认数据目录路径嵌入到二进制文件中。 实际的数据文件将在运行时从此目录路径加载。

  • NODE_ICU_DATA 环境变量:

  • --icu-data-dir CLI 参数:

当指定了多个选项时,--icu-data-dir CLI 参数具有最高优先级,其次是 NODE_ICU_DATA 环境变量,然后是 --with-icu-default-data-dir configure 选项。

ICU 能够自动查找并加载各种数据格式,但数据必须适用于 ICU 版本,且文件命名正确。数据文件最常见的名称是 icudtX[bl].dat,其中 X 表示预期的 ICU 版本,bl 表示系统的字节序。如果无法从指定目录读取预期的数据文件,Node.js 将加载失败。与当前 Node.js 版本对应的数据文件名称可以通过以下方式计算:

查看 ICU 用户指南中的 "ICU Data" 文章,了解其他支持的格式以及有关 ICU 数据的一般详细信息。

full-icu npm 模块可以通过检测运行中的 node 可执行文件的 ICU 版本并下载适当的数据文件,从而大大简化 ICU 数据的安装。通过 npm i full-icu 安装模块后,数据文件将位于 ./node_modules/full-icu。然后可以将此路径传递给 NODE_ICU_DATA--icu-data-dir,如上所示,以启用完整的 Intl 支持。

要验证是否启用了 ICU(system-icusmall-icufull-icu),只需检查 Intl 的存在性就足够了:

或者,检查 process.versions.icu(仅在启用 ICU 时定义的属性)也可以:

要检查对非英语区域设置的支持(即 full-icusystem-icu),Intl.DateTimeFormat 可以作为一个很好的区分因素:

const hasFullICU = (() => {
  try {
    const january = new Date(9e8);
    const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
    return spanish.format(january) === 'enero';
  } catch (err) {
    return false;
  }
})();

对于更详细的 Intl 支持测试,以下资源可能会有所帮助:

  • btest402:通常用于检查带有 Intl 支持的 Node.js 是否构建正确。
  • Test262:ECMAScript 的官方一致性测试套件包含一个专门针对 ECMA-402 的部分。