开发手册 欢迎您!
软件开发者资料库

国际化支持 | Node.js

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。

Node.js v8.x 中文文档


Internationalization Support#

Node.js有许多功能,使它更容易编写国际化程序.其中一些是:

Node.js(及其背后的V8引擎)在原生的C / C++代码使用[ICU] [ ] 实施这些功能。然而,其中一些为了支持世界的所有地区,需要一个非常大的ICU数据文件。因为预计多数Node.js的用户将只使用ICU的功能的一小部分,Node.js默认设置了所有ICU的数据集的一个子集。当建设或运行Node.js时提供了几个定制和扩展ICU数据集的选项。

Options for building Node.js#

To control how ICU is used in Node.js, four configure options are availableduring compilation. Additional details on how to compile Node.js are documentedin BUILDING.md.

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

An overview of available Node.js and JavaScript features for each configureoption:

nonesystem-icusmall-icufull-icu
String.prototype.normalize()none (function is no-op)fullfullfull
String.prototype.to*Case()fullfullfullfull
Intlnone (object does not exist)partial/full (depends on OS)partial (English-only)full
String.prototype.localeCompare()partial (not locale-aware)fullfullfull
String.prototype.toLocale*Case()partial (not locale-aware)fullfullfull
Number.prototype.toLocaleString()partial (not locale-aware)partial/full (depends on OS)partial (English-only)full
Date.prototype.toLocale*String()partial (not locale-aware)partial/full (depends on OS)partial (English-only)full
WHATWG URL Parserpartial (no IDN support)fullfullfull
require('buffer').transcode()none (function does not exist)fullfullfull
REPLpartial (inaccurate line editing)fullfullfull
require('util').TextDecoderpartial (basic encodings support)partial/full (depends on OS)partial (Unicode-only)full

Note: The "(not locale-aware)" designation denotes that the function carriesout its operation just like the non-Locale version of the function, if oneexists. For example, under none mode, Date.prototype.toLocaleString()'soperation is identical to that of Date.prototype.toString().

Disable all internationalization features (none)#

If this option is chosen, most internationalization features mentioned abovewill be unavailable in the resulting node binary.

Build with a pre-installed ICU (system-icu)#

Node.js can link against an ICU build already installed on the system. In fact,most Linux distributions already come with ICU installed, and this option wouldmake it possible to reuse the same set of data used by other components in theOS.

Functionalities that only require the ICU library itself, such asString.prototype.normalize() and the WHATWG URL parser, are fullysupported under system-icu. Features that require ICU locale data inaddition, such as Intl.DateTimeFormat may be fully or partiallysupported, depending on the completeness of the ICU data installed on thesystem.

Embed a limited set of ICU data (small-icu)#

This option makes the resulting binary link against the ICU library statically,and includes a subset of ICU data (typically only the English locale) withinthe node executable.

Functionalities that only require the ICU library itself, such asString.prototype.normalize() and the WHATWG URL parser, are fullysupported under small-icu. Features that require ICU locale data in addition,such as Intl.DateTimeFormat, generally only work with the English locale:

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 "M01" on small-icu// Should print "enero"

This mode provides a good balance between features and binary size, and it isthe default behavior if no --with-intl flag is passed. The official binariesare also built in this mode.

Providing ICU data at runtime#

If the small-icu option is used, one can still provide additional locale dataat runtime so that the JS methods would work for all ICU locales. Assuming thedata file is stored at /some/directory, it can be made available to ICUthrough either:

  • The NODE_ICU_DATA environment variable:

    env NODE_ICU_DATA=/some/directory node
  • The --icu-data-dir CLI parameter:

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

(If both are specified, the --icu-data-dir CLI parameter takes precedence.)

ICU is able to automatically find and load a variety of data formats, but thedata must be appropriate for the ICU version, and the file correctly named.The most common name for the data file is icudt5X[bl].dat, where 5X denotesthe intended ICU version, and b or l indicates the system's endianness.Check "ICU Data" article in the ICU User Guide for other supported formatsand more details on ICU data in general.

The full-icu npm module can greatly simplify ICU data installation bydetecting the ICU version of the running node executable and downloading theappropriate data file. After installing the module through npm i full-icu,the data file will be available at ./node_modules/full-icu. This path can bethen passed either to NODE_ICU_DATA or --icu-data-dir as shown above toenable full Intl support.

Embed the entire ICU (full-icu)#

This option makes the resulting binary link against ICU statically and includea full set of ICU data. A binary created this way has no further externaldependencies and supports all locales, but might be rather large. SeeBUILDING.md on how to compile a binary using this mode.

Detecting internationalization support#

To verify that ICU is enabled at all (system-icu, small-icu, orfull-icu), simply checking the existence of Intl should suffice:

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

Alternatively, checking for process.versions.icu, a property defined onlywhen ICU is enabled, works too:

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

To check for support for a non-English locale (i.e. full-icu orsystem-icu), Intl.DateTimeFormat can be a good distinguishing factor:

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;  }})();

For more verbose tests for Intl support, the following resources may be foundto be helpful:

  • btest402: Generally used to check whether Node.js with Intl support isbuilt correctly.
  • Test262: ECMAScript's official conformance test suite includes a sectiondedicated to ECMA-402.