Módulos ECMAScript (ES Modules)
Antes de ES6 (ECMAScript 2015), JavaScript no contaba con un sistema oficial de módulos en el lenguaje, recurriendo a patrones como IIFE o sistemas externos (CommonJS en Node.js o AMD en el navegador).
ES Modules (ESM) es el estándar oficial y nativo de JavaScript para organizar el código en archivos independientes, reutilizables y con alcance (scope) aislado.
1. Exportaciones: Nombradas y por Defecto #
A) Exportaciones Nombradas (Named Exports) #
Permite exportar múltiples funciones, constantes o clases desde un mismo archivo:
1// matematicas.js 2export const PI = 3.14159; 3 4export function sumar(a, b) { 5 return a + b; 6} 7 8export class Calculadora { 9 duplicar(n) { return n * 2; } 10}
B) Exportación por Defecto (Default Export) #
Cada archivo puede tener una única exportación principal:
1// logger.js 2export default function logMensaje(mensaje) { 3 console.log(`[LOG ${new Date().toISOString()}]: ${mensaje}`); 4}
2. Importaciones en el Consumidor #
1// main.js 2// 1. Importar exportación por defecto (puedes elegir el nombre) 3import logMensaje from './logger.js'; 4 5// 2. Importar exportaciones nombradas (con llaves) 6import { PI, sumar, Calculadora } from './matematicas.js'; 7 8// 3. Importar con alias usando 'as' 9import { sumar as sumaTotal } from './matematicas.js'; 10 11// 4. Importar todo en un espacio de nombres 12import * as MathLib from './matematicas.js'; 13 14logMensaje(`El resultado es: ${sumar(10, 20)}`);
3. Importaciones Dinámicas con import() #
La función import('ruta.js') devuelve una promesa y permite cargar módulos bajo demanda (lazy loading o división de código), reduciendo el tiempo de carga inicial de una aplicación web:
1async function iniciarModuloReportes() { 2 console.log("Cargando módulo de reportes bajo demanda..."); 3 4 // Se descarga e importa solo cuando se ejecuta la función 5 const moduloReportes = await import('./reportesAvanzados.js'); 6 moduloReportes.generarGraficosPDF(); 7}
4. Top-Level Await (ES2022) #
En los módulos ES ya no es obligatorio envolver las operaciones asíncronas en una función async autoejecutable; puedes usar await directamente en el nivel superior del archivo:
1// config.js (Módulo ES) 2const respuesta = await fetch("https://api.servidor.com/config"); 3export const configuracionRemota = await respuesta.json();
5. Módulos en el Navegador con <script type="module"> #
Para usar módulos ES directamente en páginas HTML:
1<script type="module" src="app.js"></script>
Particularidades de los Módulos en el Navegador: #
- Modo Estricto Automático: Siempre se ejecutan en
"use strict". - Ámbito Aislado: Las variables declaradas no contaminan el objeto global
window. - Carga Diferida (Deferred): Se descargan en paralelo y se ejecutan automáticamente tras parsear el documento HTML (equivalente a
defer). - CORS Obligatorio: Las peticiones a módulos están sujetas a políticas de seguridad CORS (requieren servirse mediante un servidor HTTP local o remoto, no con
file://).
Resumen del tema
Conceptos clave #
- ES Modules (ESM): estándar nativo oficial de JavaScript para modularización con análisis estático de dependencias.
- Sintaxis de Exportación:
- Nombrada:
export { a, b }(múltiples por archivo, importación con llaves). - Por defecto:
export default x(única por archivo, importación libre).
- Nombrada:
- Importación Dinámica (
import()): carga diferida asíncrona que devuelve una promesa para optimización de rendimiento. - Top-Level Await (ES2022): permite
awaiten la raíz de los módulos. <script type="module">: ejecución diferida, segura y aislada del ámbito global en navegadores.
Qué debes recordar #
Utiliza siempre ES Modules (import/export) en lugar de CommonJS (require) para asegurar compatibilidad universal, soporte de tree-shaking y Top-Level Await.