Skip to content

Soporte para internacionalización

Node.js tiene muchas características que facilitan la escritura de programas internacionalizados. Algunas de ellas son:

Node.js y el motor V8 subyacente utilizan Componentes Internacionales para Unicode (ICU) para implementar estas características en código nativo C/C++. El conjunto de datos completo de ICU se proporciona de forma predeterminada en Node.js. Sin embargo, debido al tamaño del archivo de datos de ICU, se ofrecen varias opciones para personalizar el conjunto de datos de ICU ya sea al compilar o ejecutar Node.js.

Opciones para construir Node.js

Para controlar cómo se usa ICU en Node.js, hay cuatro opciones de configure disponibles durante la compilación. En BUILDING.md se documentan detalles adicionales sobre cómo compilar Node.js.

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

Una descripción general de las características disponibles de Node.js y JavaScript para cada opción de configure:

Característicanonesystem-icusmall-icufull-icu
String.prototype.normalize()ninguna (la función es no-op)completacompletacompleta
String.prototype.to*Case()completacompletacompletacompleta
Intlninguna (el objeto no existe)parcial/completa (depende del SO)parcial (solo en inglés)completa
String.prototype.localeCompare()parcial (no tiene en cuenta la configuración regional)completacompletacompleta
String.prototype.toLocale*Case()parcial (no tiene en cuenta la configuración regional)completacompletacompleta
Number.prototype.toLocaleString()parcial (no tiene en cuenta la configuración regional)parcial/completa (depende del SO)parcial (solo en inglés)completa
Date.prototype.toLocale*String()parcial (no tiene en cuenta la configuración regional)parcial/completa (depende del SO)parcial (solo en inglés)completa
Analizador de URL heredadoparcial (sin soporte para IDN)completacompletacompleta
Analizador de URL WHATWGparcial (sin soporte para IDN)completacompletacompleta
require('node:buffer').transcode()ninguna (la función no existe)completacompletacompleta
REPLparcial (edición de línea inexacta)completacompletacompleta
require('node:util').TextDecoderparcial (soporte de codificación básica)parcial/completa (depende del SO)parcial (solo Unicode)completa
RegExp Escapes de propiedades Unicodeninguna (error de RegExp inválido)completacompletacompleta

La designación "(no tiene en cuenta la configuración regional)" indica que la función lleva a cabo su operación al igual que la versión no Locale de la función, si existe. Por ejemplo, en el modo none, la operación de Date.prototype.toLocaleString() es idéntica a la de Date.prototype.toString().

Deshabilitar todas las funciones de internacionalización (none)

Si se elige esta opción, ICU se deshabilitará y la mayoría de las funciones de internacionalización mencionadas anteriormente no estarán disponibles en el binario node resultante.

Construir con un ICU preinstalado (system-icu)

Node.js puede vincularse a una compilación de ICU ya instalada en el sistema. De hecho, la mayoría de las distribuciones de Linux ya vienen con ICU instalado, y esta opción permitiría reutilizar el mismo conjunto de datos utilizado por otros componentes del sistema operativo.

Las funcionalidades que solo requieren la propia biblioteca ICU, como String.prototype.normalize() y el analizador de URL WHATWG, son totalmente compatibles con system-icu. Las funciones que además requieren datos de configuración regional de ICU, como Intl.DateTimeFormat pueden ser total o parcialmente compatibles, dependiendo de la integridad de los datos de ICU instalados en el sistema.

Incorporar un conjunto limitado de datos ICU (small-icu)

Esta opción hace que el binario resultante se vincule estáticamente a la biblioteca ICU, e incluye un subconjunto de datos ICU (normalmente solo la configuración regional en inglés) dentro del ejecutable node.

Las funcionalidades que solo requieren la biblioteca ICU en sí, como String.prototype.normalize() y el analizador de URL WHATWG, son totalmente compatibles con small-icu. Las funciones que requieren además datos de configuración regional de ICU, como Intl.DateTimeFormat, generalmente solo funcionan con la configuración regional en 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" o "January" en small-icu, dependiendo de la configuración regional predeterminada del usuario
// Debería imprimir "enero"

Este modo proporciona un equilibrio entre las características y el tamaño binario.

Proporcionar datos ICU en tiempo de ejecución

Si se utiliza la opción small-icu, aún se pueden proporcionar datos de configuración regional adicionales en tiempo de ejecución para que los métodos JS funcionen para todas las configuraciones regionales de ICU. Suponiendo que el archivo de datos se almacena en /runtime/directory/with/dat/file, se puede poner a disposición de ICU a través de:

  • La opción de configuración --with-icu-default-data-dir: Esto solo integra la ruta del directorio de datos predeterminada en el binario. El archivo de datos real se cargará en tiempo de ejecución desde esta ruta de directorio.
  • La variable de entorno NODE_ICU_DATA:
  • El parámetro CLI --icu-data-dir:

Cuando se especifica más de uno de ellos, el parámetro CLI --icu-data-dir tiene la mayor precedencia, luego la variable de entorno NODE_ICU_DATA y luego la opción de configuración --with-icu-default-data-dir.

ICU puede encontrar y cargar automáticamente una variedad de formatos de datos, pero los datos deben ser apropiados para la versión de ICU y el archivo debe tener el nombre correcto. El nombre más común para el archivo de datos es icudtX[bl].dat, donde X denota la versión de ICU prevista, y b o l indica el orden de bytes del sistema. Node.js fallaría al cargarse si el archivo de datos esperado no se puede leer desde el directorio especificado. El nombre del archivo de datos correspondiente a la versión actual de Node.js se puede calcular con:

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

Consulte el artículo "Datos de ICU" en la Guía del usuario de ICU para obtener otros formatos admitidos y más detalles sobre los datos de ICU en general.

El módulo npm full-icu puede simplificar en gran medida la instalación de datos de ICU al detectar la versión de ICU del ejecutable node en ejecución y descargar el archivo de datos adecuado. Después de instalar el módulo a través de npm i full-icu, el archivo de datos estará disponible en ./node_modules/full-icu. Esta ruta se puede pasar a NODE_ICU_DATA o --icu-data-dir como se muestra arriba para habilitar la compatibilidad total con Intl.

Incrustar la ICU completa (full-icu)

Esta opción hace que el binario resultante se vincule estáticamente con ICU e incluya un conjunto completo de datos ICU. Un binario creado de esta manera no tiene más dependencias externas y es compatible con todas las configuraciones regionales, pero podría ser bastante grande. Este es el comportamiento predeterminado si no se pasa ningún indicador --with-intl. Los binarios oficiales también se construyen en este modo.

Detectar la compatibilidad con la internacionalización

Para verificar que ICU está habilitado en absoluto (system-icu, small-icu o full-icu), simplemente verificar la existencia de Intl debería ser suficiente:

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

Alternativamente, verificar process.versions.icu, una propiedad definida solo cuando ICU está habilitado, también funciona:

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

Para verificar la compatibilidad con una configuración regional que no sea inglés (es decir, full-icu o system-icu), Intl.DateTimeFormat puede ser un buen factor distintivo:

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 pruebas más detalladas de compatibilidad con Intl, los siguientes recursos pueden ser útiles:

  • btest402: Generalmente se usa para verificar si Node.js con compatibilidad con Intl está construido correctamente.
  • Test262: El conjunto de pruebas de conformidad oficial de ECMAScript incluye una sección dedicada a ECMA-402.