Módulos JavaScript: alcance, dependencias y ESM | Nicolás Garzón
Un módulo es una unidad de código con su propio scope y una interfaz explícita de importaciones y exportaciones.
JavaScript
Copiar
export function calculateTotal ( items ) {
return items. reduce (
( total, item ) => total + item. price,
0 ,
) ;
} JavaScript
Copiar
import { calculateTotal } from "./prices.js" ;
Sin módulos, archivos distintos pueden compartir y sobrescribir nombres globales.
JavaScript
Copiar const configuration = { } ; Con módulos, cada archivo mantiene bindings privados y expone únicamente su contrato.
JavaScript
Copiar const secret = "internal" ;
export const publicValue = "visible" ; secret no se convierte en propiedad global ni puede importarse porque no fue exportado.
Tiene scope propio.
Se ejecuta en strict mode.
Permite import y export estáticos.
Admite top-level await.
Participa en un grafo de dependencias.
Un script clásico tiene reglas de global y carga diferentes.
Texto
Copiar main.js
├─ checkout.js
│ ├─ prices.js
│ └─ payments.js
└─ ui.jsEl host resuelve, enlaza y evalúa el grafo; no ejecuta cada archivo de forma aislada sin conocer sus dependencias.
Cuando varias rutas importan el mismo módulo resuelto, comparten su instancia y estado de módulo.
JavaScript
Copiar
let count = 0 ;
export function increment ( ) {
return ++ count;
} Todos los importadores del mismo módulo observan ese count compartido.
JavaScript
Copiar console. log ( "Module loaded" ) ;
registerGlobalHandler ( ) ; Estas acciones ocurren durante evaluación aunque el importador no llame una función exportada.
Prefiere módulos que definan valores y funciones. Mantén inicialización con efectos en puntos explícitos.
JavaScript
Copiar import "./register-polyfills.js" ; Comunica que importa para ejecutar la inicialización del módulo, no para recibir bindings.
ECMAScript define registros y relaciones de módulos, pero navegadores, Node.js y bundlers deciden cómo resolver specifiers.
JavaScript
Copiar import "./local.js" ;
import "package-name" ; El primero es relativo. El segundo necesita reglas del entorno o herramientas.
HTML
Copiar < script type = " module" src = " /main.js" > </ script> Los módulos usan carga y resolución basada en URLs. Los specifiers relativos normalmente necesitan extensión y una ruta válida.
El formato puede definirse mediante extensiones o package.json. No asumas que una configuración del bundler coincide con la resolución nativa de Node.
Un singleton de módulo puede ser útil para configuración o cache, pero también introduce estado compartido.
JavaScript
Copiar let client;
export function getClient ( ) {
client ??= createClient ( ) ;
return client;
} Define quién puede reiniciarlo y cómo se prueba.
JavaScript
Copiar let configuration;
export function initializeConfig ( value ) {
if ( configuration !== undefined ) {
throw new Error ( "Configuration already initialized" ) ;
}
configuration = Object. freeze ( { ... value } ) ;
}
export function getConfig ( ) {
if ( configuration === undefined ) {
throw new Error ( "Configuration is not initialized" ) ;
}
return configuration;
} El scope protege el binding y la API expresa el ciclo de vida.
Confundir archivo con módulo en cualquier contexto.
Esperar que una variable de módulo sea global.
Introducir efectos ocultos durante import.
Usar estado de módulo sin estrategia de pruebas.
Suponer que el lenguaje resuelve paquetes por sí mismo.
Depender de alias del bundler en un runtime que no los conoce.
Crear ciclos por módulos que conocen demasiadas capas.
Un módulo tiene scope e interfaz propios.
Importaciones y exportaciones forman un grafo.
Los módulos son estrictos.
Una instancia resuelta se evalúa una vez.
El estado de módulo se comparte entre sus importadores.
Los efectos al importar deben ser intencionales.
La resolución concreta depende del host.
¿Por qué dos archivos que importan counter.js comparten el mismo contador?
Respuesta Porque ambos enlaces apuntan a la misma instancia del módulo resuelto, que se evalúa una vez y conserva su entorno.
import y export explica las formas de declarar la interfaz estática de un módulo.