Los módulos en Node.js son archivos de JavaScript que exportan funciones, objetos o valores para que otros archivos puedan usarlos.
El problema de tener todo en un solo archivo
Imagina que trabajas en el equipo de tecnología de Liverpool. Tu proyecto tiene cientos de líneas de código: lógica de pagos, conexión a base de datos, cálculo de envíos y manejo de usuarios. Todo en un solo archivo llamado app.js. Cada vez que alguien toca ese archivo, rompe algo. Nadie sabe dónde empieza ni dónde termina cada función. Ese caos tiene solución: los módulos.
Dividir tu código en módulos es como organizar un almacén. Cada área tiene su función y su lugar. Cuando necesitas algo, sabes exactamente dónde buscarlo.
El sistema CommonJS: la base de Node.js
Node.js usa por defecto un sistema llamado CommonJS. Este sistema tiene dos palabras clave que debes memorizar:
module.exports: lo que tu archivo le ofrece al mundo.require(): la forma en que un archivo pide lo que otro exporta.
Piénsalo así: module.exports es la vitrina de una tienda, y require() es el cliente que entra y toma lo que necesita.
Cómo exportar código desde un archivo
Crea un archivo llamado calculos.js. Este archivo tendrá funciones para calcular precios con IVA, algo muy común en proyectos que trabajan con el SAT.
// calculos.js
function agregarIVA(precio) {
return precio * 1.16;
}
function aplicarDescuento(precio, porcentaje) {
return precio - precio * (porcentaje / 100);
}
module.exports = { agregarIVA, aplicarDescuento };
Este archivo exporta dos funciones. Cualquier otro archivo en tu proyecto puede usarlas sin copiar ni pegar el código.
Cómo importar ese código con require()
Ahora crea un archivo main.js en la misma carpeta:
// main.js
const { agregarIVA, aplicarDescuento } = require('./calculos');
const precioBase = 1500;
const precioConIVA = agregarIVA(precioBase);
const precioFinal = aplicarDescuento(precioConIVA, 10);
console.log(`Precio base: $${precioBase}`);
console.log(`Con IVA: $${precioConIVA.toFixed(0)}`);
console.log(`Con descuento del 10%: $${precioFinal.toFixed(0)}`);
Al correr node main.js, verás esto en tu terminal:
Precio base: $1,500
Con IVA: $1,740
Con descuento del 10%: $1,566
Fíjate en el ./ antes de calculos. Ese punto y diagonal le dicen a Node.js que el archivo está en la misma carpeta. Si omites eso, Node.js buscará un módulo instalado con npm, no tu archivo local.
Módulos nativos: lo que Node.js ya trae instalado
Node.js incluye módulos que puedes usar sin instalar nada. Son parte del núcleo del sistema. Los tres más útiles al inicio son fs, path y os.
El módulo fs: leer y escribir archivos
fs significa "file system". Te permite crear, leer, modificar y borrar archivos desde tu código.
Supón que en Bimbo necesitan generar un reporte diario de ventas y guardarlo en un archivo de texto:
// reporte.js
const fs = require('fs');
const reporte = `Reporte de ventas - Bimbo\nProducto: Pan Blanco\nUnidades vendidas: 4,200\nIngreso total: $63,000`;
fs.writeFileSync('reporte.txt', reporte);
console.log('Reporte guardado correctamente.');
Este código crea el archivo reporte.txt con el contenido del reporte. writeFileSync es la versión síncrona: el programa espera a que el archivo se guarde antes de continuar.
Para leer ese mismo archivo después:
const contenido = fs.readFileSync('reporte.txt', 'utf-8');
console.log(contenido);
El módulo path: construir rutas sin errores
Las rutas de archivos cambian entre Windows, Mac y Linux. En Windows usas \, en Mac y Linux usas /. Si escribes rutas a mano, tu código falla en otra computadora.
path resuelve ese problema. Construye rutas correctas sin importar el sistema operativo:
// rutas.js
const path = require('path');
const carpetaBase = '/proyectos/femsa';
const archivo = 'inventario.json';
const rutaCompleta = path.join(carpetaBase, 'datos', archivo);
console.log(rutaCompleta);
// Resultado: /proyectos/femsa/datos/inventario.json
const extension = path.extname(archivo);
console.log(extension);
// Resultado: .json
const nombreSinExtension = path.basename(archivo, extension);
console.log(nombreSinExtension);
// Resultado: inventario
path.join() une segmentos de ruta. path.extname() extrae la extensión. path.basename() obtiene el nombre del archivo. Estos tres métodos los usarás constantemente.
El módulo os: información del sistema operativo
os te da información sobre la máquina donde corre tu aplicación. Es útil para monitorear servidores o adaptar el comportamiento según el entorno:
// sistema.js
const os = require('os');
console.log('Sistema operativo:', os.platform());
console.log('Arquitectura:', os.arch());
console.log('CPUs disponibles:', os.cpus().length);
const memoriaLibreMB = Math.round(os.freemem() / 1024 / 1024);
console.log(`Memoria libre: ${memoriaLibreMB} MB`);
console.log('Usuario del sistema:', os.userInfo().username);
Un servidor de Mercado Libre puede usar os para verificar si tiene suficiente memoria antes de procesar un lote grande de pedidos.
Errores comunes al trabajar con módulos
Hay tres errores que aparecen mucho cuando empiezas con módulos. Conocerlos ahora te ahorra horas de frustración.
Error 1: Olvidar el ./ en require()
// Incorrecto
const calculos = require('calculos');
// Correcto
const calculos = require('./calculos');
Sin ./, Node.js busca el módulo en node_modules y lanza un error MODULE_NOT_FOUND.
Error 2: No exportar lo que necesitas
// calculos.js - versión con error
function agregarIVA(precio) {
return precio * 1.16;
}
// Se olvidó module.exports
// main.js
const { agregarIVA } = require('./calculos');
console.log(agregarIVA(1000)); // TypeError: agregarIVA is not a function
Si no exportas la función, el archivo solo exporta un objeto vacío. Siempre verifica tu module.exports.
Error 3: Confundir rutas relativas y absolutas
Usa path.join(__dirname, 'archivo.txt') cuando necesites una ruta que funcione sin importar desde dónde ejecutas el script. __dirname es una variable especial de Node.js que contiene la ruta absoluta de la carpeta del archivo actual.
const fs = require('fs');
const path = require('path');
const ruta = path.join(__dirname, 'reporte.txt');
const contenido = fs.readFileSync(ruta, 'utf-8');
console.log(contenido);
Esto funciona aunque ejecutes el script desde cualquier carpeta de tu sistema.
Cómo organizar módulos en un proyecto real
Un proyecto mediano en México —digamos, una API para una tienda en línea— suele organizarse así:
proyecto/
├── src/
│ ├── calculos/
│ │ └── precios.js
│ ├── utils/
│ │ └── formato.js
│ └── reportes/
│ └── ventas.js
├── main.js
└── package.json
Cada carpeta agrupa módulos por responsabilidad. calculos/precios.js solo hace cálculos. utils/formato.js solo da formato a los datos. reportes/ventas.js solo genera reportes. Cuando algo falla, sabes exactamente dónde buscar.
Exportar un solo valor vs. múltiples valores
A veces un módulo exporta una sola cosa, como una configuración:
// config.js
module.exports = {
puerto: 3000,
empresa: "FEMSA",
version: "1.0.0"
};
// main.js
const config = require('./config');
console.log(`Iniciando ${config.empresa} en el puerto ${config.puerto}`);
// Resultado: Iniciando FEMSA en el puerto 3000
Otras veces exportas múltiples funciones usando desestructuración, como viste en el ejemplo de calculos.js.
La regla de oro de los módulos: cada archivo debe tener una sola responsabilidad clara, y todo lo que otros necesitan de él debe estar en module.exports.