Gestión de Módulos en JavaScript: Guía Completa de export, export default y CommonJS

La modularización en JavaScript es una técnnica fundamental para organizar el código en fragmentos independientes y reutilizables. Este enfoque permite gestionar las dependencias de manera eficiente, evitando colisiones en el espacio de nombres global y mejorando significativamente la escalabilidad del software.

Evolución de los Ssitemas de Módulos

  • Patrón IIFE: Utiliza expresiones de función ejecutadas inmediatamente para crear un entorno privado, exponiendo solo lo necesario a través de un objeto global.
  • CommonJS: El estándar adoptado por Node.js. Se basa en require() para importar y module.exports para exportar, funcionando de manera síncrona.
  • AMD (Asynchronous Module Definition): Diseñado para navegadores, permite la carga asíncrona de dependencias mediante la función define().
  • ES6 Modules (ESM): El estándar oficial de ECMAScript. Introduce import y export, permitiendo el análisis estático y optimizaciones como el tree-shaking.

1. Exportaciones por Defecto (export default)

Este método se utiliza para exportar un único valor principal desde un archivo. Al importar, no es necesario usar llaves y se puede asignar cualquier nombre al elemento importado.

// configuracion.js
const puerto = 8080;
export default puerto;

// main.js
import puertoServidor from './configuracion'; 
// Se puede renombrar libremente al importar

También es posible exportar objetos complejos de forma predeterminada:

// utilidades.js
const version = "1.0.0";
const entorno = "produccion";
const inicializar = () => console.log("Sistema iniciado");

export default {
  version,
  entorno,
  inicializar
}

// app.js
import core from './utilidades';
core.inicializar();

2. Exportaciones Nombradas (export)

Permiten exportar múltiples elementos desde un mismo módulo. Para importarlos, se requiere el uso de llaves {} y los nombres deben coincidir exactamente, a menos que se use un alias.

// acciones.js
export const NIVEL_LOG = 'info';

export const encender = () => {
    console.log('Dispositivo encendido');
}

export function apagar() {
    console.log('Dispositivo apagado');
}

// importacion.js
import { NIVEL_LOG as nivel, encender, apagar } from './acciones';
// O importar todo como un objeto:
// import * as gestor from './acciones';

Otra forma de declarar exportaciones nombradas es al final del archivo:

const nombreApp = "AdminPanel";
const timeout = 5000;

function obtenerConfig() {
  return { nombreApp, timeout };
}

export { nombreApp, timeout, obtenerConfig };

3. Uso Combinado de Exportaciones

Un módulo puede contener una exportación por defecto y varias exportaciones nombradas simultáneamente.

// usuario.js
const usuarioPrincipal = "Admin";
export const idSesion = "998877";

export default usuarioPrincipal;

// login.js
import usuario, { idSesion } from "./usuario";

console.log(`Usuario: ${usuario}, Sesión: ${idSesion}`);

4. Sistema de Módulos CommonJS

En entornos como Node.js, es común el uso de module.exports. Es importante notar que exports es simplemente una referencia inicial a module.exports.

// database.js
const conectar = () => { /* lógica */ };
const desconectar = () => { /* lógica */ };

module.exports = { conectar, desconectar };

// index.js
const { conectar } = require('./database');

Uso de exports individualmente:

// matetica.js
exports.sumar = (a, b) => a + b;
exports.restar = (a, b) => a - b;

// cliente.js
const mates = require('./matetica');
console.log(mates.sumar(10, 5));

5. Diferencias Clave: CommonJS vs ES6 Modules

  1. Tiempo de carga: ES6 se resuelve en tiempo de compilación (estático), mientras que CommonJS se resuelve en tiempo de ejecución (dinámico).
  2. Sintaxis: ESM utiliza import/export; CommonJS utiliza require/module.exports.
  3. Hoisting: Las importaciones de ES6 se elevan al principio del archivo; require no.
  4. Modo de carga: require() es síncrono. import es asíncrono y gestiona fases de resolución de dependencias.
  5. Copia vs Referencia: CommonJS exporta una copia de los valores (con caché). ES6 exporta una referencia dinámica y de solo lectura al valor original.
  6. Variable 'this': En CommonJS, this en el nivel superior apunta al módulo; en ES6 es undefined.
  7. Modo Estricto: ES6 Modules operan siempre bajo 'use strict' de forma nativa.
// Comportamiento en ES6
const miFuncion = () => {
    variableGlobalNoDeclarada = 50; // Error: variable no definida
};
export default miFuncion;

// Comportamiento en CommonJS
exports.miFuncion = () => {
    variableGlobalNoDeclarada = 50; // No fallará a menos que se active "use strict" manualmente
};

Etiquetas: JavaScript es6-modules CommonJS nodejs web-development

Publicado el 10-31 09:27