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 mecanismo V8 subjacente usam Componentes Internacionais para Unicode (ICU) para implementar esses recursos em código C/C++ nativo. O conjunto completo de dados ICU é 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 sã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 configure:

Recursononesystem-icusmall-icufull-icu
String.prototype.normalize()nenhum (função é no-op)completocompletocompleto
String.prototype.to*Case()completocompletocompletocompleto
Intlnenhum (objeto não existe)parcial/completo (depende do SO)parcial (somente em inglês)completo
String.prototype.localeCompare()parcial (não reconhece o locale)completocompletocompleto
String.prototype.toLocale*Case()parcial (não reconhece o locale)completocompletocompleto
Number.prototype.toLocaleString()parcial (não reconhece o locale)parcial/completo (depende do SO)parcial (somente em inglês)completo
Date.prototype.toLocale*String()parcial (não reconhece o locale)parcial/completo (depende do SO)parcial (somente 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 (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 (somente Unicode)completo
RegExp Unicode Property Escapesnenhum (erro RegExp inválido)completocompletocompleto

A designação "(não reconhece o locale)" indica que a função realiza sua operação exatamente como a versão não-Locale da função, caso exista. 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á disponível 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. Na verdade, a maioria das distribuições Linux já vem com o ICU instalado, e esta opção tornaria possível reutilizar o mesmo conjunto de dados usado por outros componentes do SO.

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

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

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

Funcionalidades que exigem apenas a biblioteca ICU, como String.prototype.normalize() e o analisador WHATWG URL, são totalmente suportadas em small-icu. Recursos que exigem dados de localidade ICU adicionais, como Intl.DateTimeFormat, geralmente funcionam apenas com o local 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))
// Imprime "January"
console.log(spanish.format(january))
// Imprime "M01" ou "January" em small-icu, dependendo da localidade padrão do usuário
// Deve imprimir "enero"

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

Fornecendo dados da ICU em tempo de execução

Se a opção small-icu for usada, ainda é possível fornecer dados de localidade adicionais 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 deste 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, por fim, 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 ter o nome correto. O nome mais comum para o arquivo de dados é icudtX[bl].dat, onde X indica a versão pretendida da ICU e b ou l indica a endianness do sistema. O Node.js falhará ao carregar se o arquivo de dados esperado não puder ser lido do 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 obter outros formatos suportados e mais detalhes sobre os dados da ICU em geral.

O módulo npm full-icu pode simplificar bastante a instalação de dados da ICU ao detectar a versão da ICU do executável node em execução e baixar o arquivo de dados apropriado. Após instalar o módulo por meio de npm i full-icu, o arquivo de dados estará disponível em ./node_modules/full-icu. Este caminho pode ser passado para NODE_ICU_DATA ou --icu-data-dir, conforme mostrado acima, para habilitar o suporte total para Intl.

Incorporar o ICU inteiro (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 todos os locais, 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.

Detetando suporte de internacionalização

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

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

Alternativamente, verificar por 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 um local não 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 detalhados para 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 oficial de testes de conformidade do ECMAScript inclui uma seção dedicada ao ECMA-402.