Saltar al contenido principal

Módulos en Node.js

En Node.js, los módulos son bloques de código independientes que pueden exportar funciones, objetos o valores para ser reutilizados en otras partes de una aplicación. Esta organización permite mantener el código más limpio, modular y fácil de mantener. Node.js incluye varios módulos integrados, como fs para trabajar con archivos o http para crear servidores, y también permite crear módulos personalizados.

Al trabajar con módulos en Node.js, se recomienda dividir el código en partes pequeñas y reutilizables, usar nombres claros para los archivos y evitar dependencias circulares. Para módulos propios, es buena idea exportar solo lo necesario y no toda la funcionalidad interna, manteniendo un encapsulamiento limpio. Además, cuando se trabaja con ESM, es conveniente mantener la coherencia de import/export en todo el proyecto.

CommonJS (require y module.exports)

El sistema de módulos original de Node.js se llama CommonJS. Para importar un módulo se utiliza require(), y para exportar valores o funciones desde un módulo se usa module.exports.

Ejemplo de módulo personalizado (math.js):

// math.js
function sumar(a, b) {
return a + b;
}

function restar(a, b) {
return a - b;
}

module.exports = { sumar, restar };

Ejemplo de uso en otro archivo (app.js):

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

console.log(math.sumar(5, 3)); // 8
console.log(math.restar(5, 3)); // 2

ES Modules (import y export)

A partir de ES6, Node.js soporta ES Modules (ESM), que utilizan la sintaxis import y export. Esto permite una forma más clara y estandarizada de organizar el código, compatible con navegadores modernos y frameworks actuales. Para usar ESM en Node.js, podemos cambiar la extensión de los archivos a .mjs o indicar "type": "module" en el package.json del proyecto.

Exportaciones nombradas

Las exportaciones nombradas permiten exportar varias funciones, objetos o clases desde un mismo archivo. Cada exportación debe ser importada utilizando el mismo nombre que se definió al exportarla.

Ejemplo: exportar varias funciones

// math.mjs
export function sumar(a, b) {
return a + b;
}

export function restar(a, b) {
return a - b;
}

export function multiplicar(a, b) {
return a * b;
}

Importación de funciones nombradas

import { sumar, restar } from './math.mjs';

console.log(sumar(5, 3)); // 8
console.log(restar(5, 3)); // 2

También se pueden importar todas las exportaciones de un módulo usando un alias:

import * as math from './math.mjs';

console.log(math.multiplicar(4, 3)); // 12

Exportación por defecto (default)

Un módulo puede tener una exportación por defecto, que se importa sin necesidad de usar llaves {}. Esto es útil cuando el módulo exporta una función principal, un objeto o una clase.

Ejemplo: exportación de función por defecto

// saludo.mjs
export default function saludar(nombre) {
return `Hola, ${nombre}!`;
}

Importación de exportación por defecto

import saludar from './saludo.mjs';

console.log(saludar("Ana")); // Hola, Ana!

Exportar una clase

Se pueden exportar clases de la misma manera que funciones, ya sea de forma nombrada o por defecto:

Exportación nombrada de clase

// persona.mjs
export class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}

saludar() {
return `Hola, soy ${this.nombre}`;
}
}

Importación de clase

import { Persona } from './persona.mjs';

const p = new Persona("Carlos", 30);
console.log(p.saludar()); // Hola, soy Carlos

Exportación por defecto de clase

// animal.mjs
export default class Animal {
constructor(especie) {
this.especie = especie;
}

info() {
return `Este es un ${this.especie}`;
}
}
import Animal from './animal.mjs';

const a = new Animal("gato");
console.log(a.info()); // Este es un gato

Exportar un objeto con múltiples funciones

Otra forma habitual es exportar un objeto que agrupe varias funciones, lo que permite importar todo de forma unificada:

// calculadora.mjs
function sumar(a, b) { return a + b; }
function restar(a, b) { return a - b; }

export default {
sumar,
restar
};
import calculadora from './calculadora.mjs';

console.log(calculadora.sumar(3, 4)); // 7
console.log(calculadora.restar(10, 6)); // 4

Buenas prácticas con ES Modules

Se recomienda mantener coherencia en todo el proyecto, usando ya sea exportaciones nombradas o por defecto, pero evitando mezclarlas innecesariamente. Para módulos que exportan varias funciones, objetos o clases, las exportaciones nombradas suelen ser más claras, mientras que las exportaciones por defecto son útiles para un elemento principal del módulo. Mantener un estilo consistente ayuda a la legibilidad y al mantenimiento del código.