Soporte para internacionalización
Node.js tiene muchas características que facilitan la escritura de programas internacionalizados. Algunas de ellas son:
Funciones sensibles a la configuración regional o conscientes de Unicode en la Especificación del lenguaje ECMAScript:
Todas las funcionalidades descritas en la Especificación de la API de internacionalización de ECMAScript (también conocida como ECMA-402):
- Objeto
Intl
- Métodos sensibles a la configuración regional como
String.prototype.localeCompare()
yDate.prototype.toLocaleString()
- Objeto
Soporte para nombres de dominio internacionalizados (IDN) del analizador de URL de WHATWG
Edición de líneas REPL más precisa
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ística | none | system-icu | small-icu | full-icu |
---|---|---|---|---|
String.prototype.normalize() | ninguna (la función es no-op) | completa | completa | completa |
String.prototype.to*Case() | completa | completa | completa | completa |
Intl | ninguna (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) | completa | completa | completa |
String.prototype.toLocale*Case() | parcial (no tiene en cuenta la configuración regional) | completa | completa | completa |
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 heredado | parcial (sin soporte para IDN) | completa | completa | completa |
Analizador de URL WHATWG | parcial (sin soporte para IDN) | completa | completa | completa |
require('node:buffer').transcode() | ninguna (la función no existe) | completa | completa | completa |
REPL | parcial (edición de línea inexacta) | completa | completa | completa |
require('node:util').TextDecoder | parcial (soporte de codificación básica) | parcial/completa (depende del SO) | parcial (solo Unicode) | completa |
RegExp Escapes de propiedades Unicode | ninguna (error de RegExp inválido) | completa | completa | completa |
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:
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:
;`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:
const hasICU = typeof Intl === 'object'
Alternativamente, verificar process.versions.icu
, una propiedad definida solo cuando ICU está habilitado, también funciona:
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:
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: