Node.js v20.7.0 文档


目录

国际化支持#

Node.js 有很多特性可以让编写国际化程序变得更容易。 它们之中有一些是:

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

构建 Node.js 的选项#

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

  • --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() 是一样的。

禁用所有国际化功能 (none)#

如果选择此选项,ICU 将被禁用,并且上面提到的大多数国际化功能将在生成的 node 二进制文件中为 unavailable

使用预装的 ICU (system-icu) 构建#

Node.js 可以链接到系统上已安装的 ICU。 事实上,大多数 Linux 发行版已经安装了 ICU,这个选项可以复用操作系统中其他组件使用的相同数据集。

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

嵌入一组有限的 ICU 数据 (small-icu)#

此选项静态地生成针对 ICU 库的二进制链接,并在 node 可执行文件中包含 ICU 数据的子集(通常只有英文区域设置)。

small-icu 完全支持仅需要 ICU 库本身的功能,例如 String.prototype.normalize()WHATWG URL 解析器。 另外需要 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));
// Prints "January"
console.log(spanish.format(january));
// Prints either "M01" or "January" on small-icu, depending on the user’s default locale
// Should print "enero" 

此模式提供了特性和二进制大小之间的平衡。

在运行时提供 ICU 数据#

如果使用 small-icu 选项,则仍然可以在运行时提供额外的语言环境数据,以便 JS 方法适用于所有 ICU 语言环境。 假设数据文件存储在 /some/directory,它可以通过以下任一方式提供给 ICU:

  • NODE_ICU_DATA 环境变量:

    env NODE_ICU_DATA=/some/directory node 
  • --icu-data-dir 命令行参数:

    node --icu-data-dir=/some/directory 

(如果两者都指定,则 --icu-data-dir 命令行参数优先。)

ICU 能够自动查找和加载多种数据格式,但数据必须适合 ICU 版本,并且文件命名正确。 数据文件最常见的名称是 icudt6X[bl].dat,其中 6X 表示预期的 ICU 版本,而 bl 表示系统的字节序。 查看 ICU 用户指南中的 "ICU 数据" 文章,了解其他支持的格式以及有关 ICU 数据的更多详细信息。

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

嵌入整个 ICU (full-icu)#

此选项使生成的二进制链接与 ICU 静态地关联并包含全套 ICU 数据。 以这种方式创建的二进制文件没有进一步的外部依赖并支持所有语言环境,但可能相当大。 如果没有传入 --with-intl 标志,则这是默认行为。 官方的二进制文件也是以这种模式构建的。

检测国际化支持#

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

const hasICU = typeof Intl === 'object'; 

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

const hasICU = typeof process.versions.icu === 'string'; 

要检查对非英语语言环境(即 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 的部分。