国際化のサポート#

Node.js には、国際化されたプログラムをより簡単に書くための多くの機能があります。そのうちのいくつかを以下に示します。

Node.js とその基盤となる V8 エンジンは、これらの機能をネイティブの C/C++ コードで実装するために International Components for Unicode (ICU) を使用しています。デフォルトでは、Node.js によって完全な ICU データセットが提供されます。しかし、ICU データファイルのサイズが大きいため、Node.js のビルド時または実行時に ICU データセットをカスタマイズするためのいくつかのオプションが提供されています。

Node.js のビルドオプション#

Node.js で ICU がどのように使用されるかを制御するために、コンパイル時に 4 つの 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()なし (関数は no-op)完全完全完全
String.prototype.to*Case()完全完全完全完全
Intlなし (オブジェクトは存在しない)部分的/完全 (OS に依存)部分的 (英語のみ)完全
String.prototype.localeCompare()部分的 (ロケール非対応)完全完全完全
String.prototype.toLocale*Case()部分的 (ロケール非対応)完全完全完全
Number.prototype.toLocaleString()部分的 (ロケール非対応)部分的/完全 (OS に依存)部分的 (英語のみ)完全
Date.prototype.toLocale*String()部分的 (ロケール非対応)部分的/完全 (OS に依存)部分的 (英語のみ)完全
レガシー URL パーサー部分的 (IDN サポートなし)完全完全完全
WHATWG URL パーサー部分的 (IDN サポートなし)完全完全完全
require('node:buffer').transcode()なし (関数は存在しない)完全完全完全
REPL部分的 (不正確な行編集)完全完全完全
require('node:util').TextDecoder部分的 (基本的なエンコーディングのみサポート)部分的/完全 (OS に依存)部分的 (Unicode のみ)完全
RegExp の Unicode プロパティエスケープなし (無効な RegExp エラー)完全完全完全

「(ロケール非対応)」という表記は、その関数が、もし存在すれば、非 Locale 版の関数と全く同じように動作することを意味します。例えば、none モードでは、Date.prototype.toLocaleString() の動作は Date.prototype.toString() の動作と同一です。

すべての国際化機能を無効にする (none)#

このオプションを選択した場合、ICU は無効になり、上記で述べた国際化機能のほとんどは、生成される node バイナリで利用できなくなります

プリインストールされた ICU でビルドする (system-icu)#

Node.js はシステムに既にインストールされている ICU ビルドに対してリンクすることができます。実際、ほとんどの Linux ディストリビューションには既に ICU がインストールされており、このオプションを使用すると、OS 内の他のコンポーネントが使用しているのと同じデータセットを再利用することが可能になります。

String.prototype.normalize()WHATWG URL パーサー のように、ICU ライブラリ自体のみを必要とする機能は system-icu で完全にサポートされます。Intl.DateTimeFormat のように、さらに ICU のロケールデータを必要とする機能は、システムにインストールされている ICU データの完全性に応じて、完全または部分的にサポートされる場合があります

限定された ICU データセットを組み込む (small-icu)#

このオプションは、生成されるバイナリが ICU ライブラリに静的にリンクし、ICU データの一部 (通常は英語ロケールのみ) を node 実行ファイル内に含めるようにします。

String.prototype.normalize()WHATWG URL パーサー のように、ICU ライブラリ自体のみを必要とする機能は small-icu で完全にサポートされます。Intl.DateTimeFormat のように、さらに ICU のロケールデータを必要とする機能は、一般的に英語ロケールでのみ動作します。

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 ロケールで動作するようにできます。データファイルが /runtime/directory/with/dat/file に保存されていると仮定すると、以下のいずれかの方法で ICU にデータを提供できます。

  • --with-icu-default-data-dir configure オプション

    ./configure --with-icu-default-data-dir=/runtime/directory/with/dat/file --with-intl=small-icu 

    これはデフォルトのデータディレクトリのパスをバイナリに埋め込むだけです。実際のデータファイルは実行時にこのディレクトリパスから読み込まれます。

  • NODE_ICU_DATA 環境変数

    env NODE_ICU_DATA=/runtime/directory/with/dat/file node 
  • --icu-data-dir CLI パラメータ

    node --icu-data-dir=/runtime/directory/with/dat/file 

複数が指定された場合、--icu-data-dir CLI パラメータが最も高い優先順位を持ち、次に NODE_ICU_DATA 環境変数、そして --with-icu-default-data-dir configure オプションの順になります。

ICU はさまざまなデータ形式を自動的に見つけてロードすることができますが、データは ICU のバージョンに適したものであり、ファイル名が正しくなければなりません。データファイルの最も一般的な名前は icudtX[bl].dat です。ここで X は対象の ICU バージョンを示し、b または l はシステムのエンディアンを示します。期待されるデータファイルが指定されたディレクトリから読み取れない場合、Node.js のロードは失敗します。現在の Node.js バージョンに対応するデータファイルの名前は、次のように計算できます。

`icudt${process.versions.icu.split('.')[0]}${os.endianness()[0].toLowerCase()}.dat`; 

その他のサポートされている形式や ICU データ全般に関する詳細については、ICU ユーザーガイドの "ICU Data" の記事を確認してください。

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-icu, small-icu, または full-icu) を確認するには、単に Intl の存在を確認するだけで十分です。

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

あるいは、ICU が有効な場合にのみ定義されるプロパティである process.versions.icu を確認する方法もあります。

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

英語以外のロケール (つまり full-icu または system-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 専用のセクションが含まれています。