Skip to content

Suporte à internacionalização

O Node.js possui muitos recursos que facilitam a escrita de programas internacionalizados. Alguns deles são:

O Node.js e o motor V8 subjacente usam Componentes Internacionais para Unicode (ICU) para implementar esses recursos em código C/C++ nativo. O conjunto de dados ICU completo é fornecido pelo Node.js por padrão. No entanto, devido ao tamanho do arquivo de dados ICU, várias opções são fornecidas para personalizar o conjunto de dados ICU durante a construção ou execução do Node.js.

Opções para construir o Node.js

Para controlar como o ICU é usado no Node.js, quatro opções de configure estão disponíveis durante a compilação. Detalhes adicionais sobre como compilar o Node.js estão documentados em BUILDING.md.

  • --with-intl=none/--without-intl
  • --with-intl=system-icu
  • --with-intl=small-icu
  • --with-intl=full-icu (padrão)

Uma visão geral dos recursos disponíveis do Node.js e JavaScript para cada opção de configure:

Recursononesystem-icusmall-icufull-icu
String.prototype.normalize()nenhum (a função não faz nada)completocompletocompleto
String.prototype.to*Case()completocompletocompletocompleto
Intlnenhum (o objeto não existe)parcial/completo (depende do SO)parcial (apenas em inglês)completo
String.prototype.localeCompare()parcial (não reconhece a localidade)completocompletocompleto
String.prototype.toLocale*Case()parcial (não reconhece a localidade)completocompletocompleto
Number.prototype.toLocaleString()parcial (não reconhece a localidade)parcial/completo (depende do SO)parcial (apenas em inglês)completo
Date.prototype.toLocale*String()parcial (não reconhece a localidade)parcial/completo (depende do SO)parcial (apenas em inglês)completo
Analisador de URL Legadoparcial (sem suporte a IDN)completocompletocompleto
Analisador de URL WHATWGparcial (sem suporte a IDN)completocompletocompleto
require('node:buffer').transcode()nenhum (a função não existe)completocompletocompleto
REPLparcial (edição de linha imprecisa)completocompletocompleto
require('node:util').TextDecoderparcial (suporte a codificações básicas)parcial/completo (depende do SO)parcial (apenas Unicode)completo
RegExp Unicode Property Escapesnenhum (erro RegExp inválido)completocompletocompleto
A designação "(não reconhece a localidade)" denota que a função executa sua operação da mesma forma que a versão não-Locale da função, se existir. Por exemplo, no modo none, a operação de Date.prototype.toLocaleString() é idêntica à de Date.prototype.toString().

Desativar todos os recursos de internacionalização (none)

Se esta opção for escolhida, o ICU será desativado e a maioria dos recursos de internacionalização mencionados acima não estarão disponíveis no binário node resultante.

Construir com um ICU pré-instalado (system-icu)

O Node.js pode ser vinculado a uma versão do ICU já instalada no sistema. De fato, a maioria das distribuições Linux já vem com o ICU instalado, e essa opção possibilitaria reutilizar o mesmo conjunto de dados usado por outros componentes no sistema operacional.

Funcionalidades que requerem apenas a biblioteca ICU em si, como String.prototype.normalize() e o analisador de URL WHATWG, são totalmente suportadas em system-icu. Recursos que também exigem dados de localidade do ICU, como Intl.DateTimeFormat podem ser total ou parcialmente suportados, dependendo da integridade dos dados do ICU instalados no sistema.

Incorporar um conjunto limitado de dados do ICU (small-icu)

Esta opção faz com que o binário resultante seja vinculado à biblioteca ICU estaticamente e inclui um subconjunto de dados do ICU (normalmente apenas a localidade em inglês) dentro do executável node.

Funcionalidades que requerem apenas a biblioteca ICU em si, como String.prototype.normalize() e o analisador de URL WHATWG, são totalmente suportadas em small-icu. Recursos que também exigem dados de localidade do ICU, como Intl.DateTimeFormat, geralmente funcionam apenas com a localidade em inglês:

js
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"

Este modo fornece um equilíbrio entre recursos e tamanho do binário.

Fornecendo dados da ICU em tempo de execução

Se a opção small-icu for usada, ainda é possível fornecer dados adicionais de localidade em tempo de execução para que os métodos JS funcionem para todas as localidades da ICU. Supondo que o arquivo de dados esteja armazenado em /runtime/directory/with/dat/file, ele pode ser disponibilizado para a ICU por meio de:

  • A opção de configuração --with-icu-default-data-dir: Isso apenas incorpora o caminho do diretório de dados padrão no binário. O arquivo de dados real será carregado em tempo de execução a partir desse caminho de diretório.
  • A variável de ambiente NODE_ICU_DATA:
  • O parâmetro CLI --icu-data-dir:

Quando mais de um deles é especificado, o parâmetro CLI --icu-data-dir tem a maior precedência, seguido pela variável de ambiente NODE_ICU_DATA e, em seguida, a opção de configuração --with-icu-default-data-dir.

A ICU é capaz de encontrar e carregar automaticamente uma variedade de formatos de dados, mas os dados devem ser apropriados para a versão da ICU e o arquivo deve ser nomeado corretamente. O nome mais comum para o arquivo de dados é icudtX[bl].dat, onde X denota a versão pretendida da ICU e b ou l indica o endianness do sistema. O Node.js falhará ao carregar se o arquivo de dados esperado não puder ser lido no diretório especificado. O nome do arquivo de dados correspondente à versão atual do Node.js pode ser calculado com:

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

Consulte o artigo "Dados da ICU" no Guia do Usuário da ICU para outros formatos suportados e mais detalhes sobre os dados da ICU em geral.

O módulo npm full-icu pode simplificar muito a instalação de dados da ICU, detectando a versão da ICU do executável node em execução e baixando o arquivo de dados apropriado. Depois de instalar o módulo através de npm i full-icu, o arquivo de dados estará disponível em ./node_modules/full-icu. Este caminho pode então ser passado para NODE_ICU_DATA ou --icu-data-dir como mostrado acima para habilitar o suporte completo a Intl.

Incorporar todo o ICU (full-icu)

Esta opção faz com que o binário resultante se vincule ao ICU estaticamente e inclua um conjunto completo de dados do ICU. Um binário criado desta forma não tem mais dependências externas e suporta todas as localidades, mas pode ser bastante grande. Este é o comportamento padrão se nenhum sinalizador --with-intl for passado. Os binários oficiais também são construídos neste modo.

Detectando suporte à internacionalização

Para verificar se o ICU está ativado (system-icu, small-icu ou full-icu), simplesmente verificar a existência de Intl deve ser suficiente:

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

Alternativamente, verificar process.versions.icu, uma propriedade definida apenas quando o ICU está habilitado, também funciona:

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

Para verificar o suporte a uma localidade que não seja inglês (ou seja, full-icu ou system-icu), Intl.DateTimeFormat pode ser um bom fator de distinção:

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

Para testes mais verbosos de suporte a Intl, os seguintes recursos podem ser úteis:

  • btest402: Geralmente usado para verificar se o Node.js com suporte a Intl foi construído corretamente.
  • Test262: O conjunto de testes de conformidade oficial do ECMAScript inclui uma seção dedicada ao ECMA-402.