Compartir en Twitter
Go to Homepage

GUÍA COMPLETA DE MÓDULOS EN JAVASCRIPT 2025

November 26, 2025

Introducción a los Módulos en JavaScript

Los módulos en JavaScript permiten organizar el código en unidades reutilizables, promoviendo una arquitectura limpia y mantenible. Desde sus inicios, JavaScript no contaba con un sistema nativo de módulos, lo que llevó al uso de patrones como IIFE (Immediately Invoked Function Expressions) y bibliotecas externas. Con la llegada de ECMAScript 2015 (ES6), los módulos ES (ECMAScript Modules o ESM) se convirtieron en el estándar nativo, transformando la forma en que los desarrolladores estructuran aplicaciones. En 2025, los módulos son esenciales en proyectos web, desde aplicaciones frontend hasta servidores Node.js. Este tutorial aborda la evolución de los módulos, su configuración, uso práctico y mejores prácticas, con ejemplos actualizados para entornos modernos.

Antes de ES6, los desarrolladores usaban patrones como módulos de cierre automático para encapsular código. Estos patrones, aunque funcionales, eran propensos a errores en proyectos grandes debido a la falta de un sistema estandarizado. La introducción de CommonJS en Node.js marcó un avance, permitiendo módulos síncronos ampliamente adoptados en entornos de servidor. Sin embargo, CommonJS no era ideal para navegadores debido a su naturaleza síncrona. Los módulos ES resolvieron estas limitaciones al ofrecer un sistema asíncrono compatible con navegadores y servidores, consolidándose como el estándar en 2025.

Evolución de los Módulos en JavaScript

La evolución de los módulos refleja los cambios en las necesidades de los desarrolladores. En los primeros días de JavaScript, el código se escribía en scripts globales, lo que generaba conflictos de nombres y dificultades de mantenimiento. Los patrones como IIFE surgieron para crear ámbitos aislados:

(function () {
    var mensaje = "Hola, mundo";
    console.log(mensaje);
})();

Este enfoque, aunque útil, no escalaba bien. CommonJS, introducido por Node.js, permitió definir módulos con module.exports y require:

// math.js
module.exports = {
    sumar: (a, b) => a + b,
};

// app.js
const math = require("./math");
console.log(math.sumar(2, 3)); // 5

CommonJS fue un gran avance, pero su carga síncrona lo hacía ineficiente para navegadores. Los módulos ES, introducidos en ES6, trajeron una sintaxis más clara y soporte nativo en navegadores:

// math.js
export const sumar = (a, b) => a + b;

// app.js
import { sumar } from "./math.js";
console.log(sumar(2, 3)); // 5

En 2025, los módulos ES dominan debido a su compatibilidad universal y soporte en herramientas como Webpack, Vite y Deno. Node.js, que inicialmente usaba CommonJS, ahora soporta ESM de forma nativa, aunque permite coexistencia con CommonJS para proyectos legados.

Configuración de un Proyecto con Módulos ES

Para usar módulos ES en 2025, es necesario configurar el entorno correctamente. En un proyecto Node.js, el archivo package.json debe incluir la propiedad "type": "module" para indicar que se usan módulos ES:

{
    "name": "mi-proyecto",
    "version": "1.0.0",
    "type": "module"
}

Sin esta configuración, Node.js asume CommonJS, lo que puede causar errores al usar import y export. Para navegadores, los módulos ES requieren que los archivos se sirvan a través de un servidor HTTP debido a restricciones de seguridad. Un entorno de desarrollo con Vite es ideal:

npm create vite@latest mi-proyecto -- --template vanilla
cd mi-proyecto
npm install
npm run dev

La estructura de un proyecto típico podría ser:

mi-proyecto/
├── node_modules/
├── index.html
├── main.js
├── math.js
└── package.json

En index.html, se carga el script principal con el atributo type="module":

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8" />
        <title>Proyecto con Módulos</title>
    </head>
    <body>
        <script type="module" src="main.js"></script>
    </body>
</html>

Esto permite importar módulos en main.js:

import { sumar } from "./math.js";
console.log(sumar(5, 10)); // 15

Sintaxis de Módulos ES

Los módulos ES ofrecen una sintaxis flexible para exportar e importar código. Existen dos tipos principales de exportaciones: nombradas y por defecto.

Exportaciones Nombradas

Las exportaciones nombradas permiten exportar múltiples valores desde un módulo:

// utils.js
export const PI = 3.14159;
export function cuadrado(num) {
    return num * num;
}

Estos valores se importan usando la misma nomenclatura:

// main.js
import { PI, cuadrado } from "./utils.js";
console.log(PI); // 3.14159
console.log(cuadrado(4)); // 16

Es posible renombrar al importar usando as:

import { PI as constantePi, cuadrado as elevarAlCuadrado } from "./utils.js";
console.log(constantePi); // 3.14159
console.log(elevarAlCuadrado(4)); // 16

Exportaciones por Defecto

Las exportaciones por defecto permiten exportar un único valor principal:

// config.js
export default {
    apiUrl: "https://api.ejemplo.com",
    timeout: 5000,
};

Se importan sin llaves y con cualquier nombre:

// main.js
import configuracion from "./config.js";
console.log(configuracion.apiUrl); // https://api.ejemplo.com

Importaciones Dinámicas

Las importaciones dinámicas, introducidas en ES2020, permiten cargar módulos bajo demanda, lo cual es útil para optimizar el rendimiento:

// main.js
async function cargarModulo() {
    const { sumar } = await import("./math.js");
    console.log(sumar(2, 3)); // 5
}
cargarModulo();

Este enfoque es ideal para cargar módulos pesados solo cuando se necesitan, mejorando la optimización de carga inicial en aplicaciones web.

Diferencias entre CommonJS y Módulos ES

Aunque CommonJS y ESM coexisten en Node.js, sus diferencias son significativas. CommonJS usa require y module.exports, mientras que ESM usa import y export. CommonJS es síncrono, lo que lo hace adecuado para servidores, pero ineficiente en navegadores. ESM, al ser asíncrono, es compatible con la carga diferida en navegadores.

Otra diferencia clave es la resolución de rutas. En CommonJS, los archivos no requieren la extensión .js:

const math = require("./math");

En ESM, la extensión es obligatoria:

import { sumar } from "./math.js";

En 2025, la mayoría de los proyectos nuevos usan ESM debido a su estandarización y soporte en herramientas modernas. Sin embargo, CommonJS sigue siendo relevante en proyectos legados o en módulos de Node.js que aún no han migrado.

Mejores Prácticas para Módulos

Adoptar buenas prácticas asegura que los módulos sean mantenibles y escalables. A continuación, se presentan recomendaciones clave:

Usar Exportaciones Nombradas para Claridad

Las exportaciones nombradas son más explícitas y facilitan el seguimiento de dependencias:

// Preferir
export const calcularArea = (r) => PI * r * r;

// Evitar
const calcularArea = (r) => PI * r * r;
export default calcularArea;

Mantener Módulos Pequeños

Cada módulo debe tener una única responsabilidad. Por ejemplo, separar funciones matemáticas y utilidades de configuración:

// math.js
export const sumar = (a, b) => a + b;

// config.js
export default { apiUrl: "https://api.ejemplo.com" };

Evitar Importaciones Circulares

Las importaciones circulares, donde dos módulos se importan mutuamente, pueden causar errores. Para evitarlas, reestructura el código:

// Evitar
// a.js
import { b } from "./b.js";
export const a = b + 1;

// b.js
import { a } from "./a.js";
export const b = a + 1;

// Solución
// utils.js
export const incrementar = (num) => num + 1;

// a.js
import { incrementar } from "./utils.js";
export const a = incrementar(0);

Usar Herramientas de Bundling

Herramientas como Vite o Webpack optimizan los módulos para producción, combinándolos en un solo archivo para reducir las solicitudes HTTP:

npm run build

Esto genera una carpeta dist con los archivos optimizados:

dist/
├── index.html
├── assets/
│   └── main.js

Módulos en Node.js en 2025

Node.js ha evolucionado para priorizar ESM, pero sigue soportando CommonJS. Para usar ESM, asegúrate de incluir "type": "module" en package.json. Si necesitas interoperar con CommonJS, puedes importar módulos CommonJS en ESM:

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const moduloLegacy = require("./modulo-legacy");

Para módulos ESM en Node.js, las rutas relativas deben incluir la extensión .js, y las importaciones dinámicas son útiles para cargar condicionalmente:

// main.js
if (condicion) {
    const { funcion } = await import("./modulo.js");
    funcion();
}

En 2025, Deno y Bun, alternativas a Node.js, también soportan ESM de forma nativa, eliminando la necesidad de configuraciones adicionales.

Módulos en Navegadores

En navegadores, los módulos ES se cargan con el atributo type="module". Para optimizar la carga, usa el atributo defer o importaciones dinámicas:

<script type="module">
    import { iniciar } from "./app.js";
    iniciar();
</script>

Los navegadores modernos soportan ESM sin necesidad de herramientas adicionales, pero para proyectos grandes, un bundler como Vite es esencial para manejar dependencias y optimizar el rendimiento.

Depuración de Módulos

Los errores comunes al trabajar con módulos incluyen rutas incorrectas, configuraciones faltantes en package.json y conflictos entre CommonJS y ESM. Para depurar, verifica lo siguiente:

  • Asegúrate de que "type": "module" está en package.json para ESM.
  • Incluye la extensión .js en las importaciones ESM.
  • Usa herramientas como la consola de desarrollador en navegadores o node --trace-warnings para identificar errores.

Por ejemplo, un error común es:

SyntaxError: Cannot use import statement outside a module

Solución: Agrega "type": "module" en package.json o usa el atributo type="module" en el script HTML.

Futuro de los Módulos en JavaScript

En 2025, los módulos ES son el estándar, pero el ecosistema sigue evolucionando. Propuestas como los módulos JSON integrados permiten importar archivos JSON directamente:

import datos from "./datos.json" assert { type: "json" };
console.log(datos);

Además, el soporte para módulos en WebAssembly está ganando tracción, permitiendo integrar código compilado en JavaScript. Herramientas como Vite y esbuild continúan optimizando la experiencia de desarrollo, haciendo que los módulos sean más accesibles y eficientes.

Conclusiones

Los módulos en JavaScript han transformado la forma en que los desarrolladores organizan y mantienen el código. Desde los días de scripts globales hasta la adopción de módulos ES, la evolución refleja un enfoque hacia la modularidad y la escalabilidad. En 2025, los módulos ES son la base de los proyectos web y de servidor, con soporte universal en navegadores y entornos como Node.js, Deno y Bun. Al adoptar mejores prácticas, como mantener módulos pequeños y usar herramientas de bundling, los desarrolladores pueden crear aplicaciones robustas y eficientes. Este tutorial proporciona una base sólida para dominar los módulos, con ejemplos prácticos que puedes aplicar en tus proyectos. Explora las herramientas y técnicas mencionadas para llevar tus habilidades de programación al siguiente nivel.