# Módulos de Node.js y NPM
Node.js tiene un poderoso sistema de módulos que te permite organizar código en archivos reutilizables. Aprende sobre CommonJS, ES Modules, módulos integrados y gestión de paquetes con NPM.
## Sistema de Módulos
### CommonJS (require/module.exports)
El sistema de módulos tradicional de Node.js:
```javascript
// math.js - Exportar funciones
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
// Exportar funciones individuales
module.exports = {
add,
subtract
};
// O exportar por defecto
module.exports = add;
```
```javascript
// app.js - Importar módulo
const math = require('./math');
console.log(math.add(5, 3)); // 8
console.log(math.subtract(10, 4)); // 6
// Desestructurar
const { add, subtract } = require('./math');
console.log(add(2, 3)); // 5
```
### ES Modules (import/export)
Sintaxis moderna de módulos de JavaScript (requiere .mjs o "type": "module" en package.json):
```javascript
// math.mjs - Exportaciones nombradas
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export const PI = 3.14159;
// Exportación por defecto
export default function multiply(a, b) {
return a * b;
}
```
```javascript
// app.mjs - Importar módulo
import multiply, { add, subtract, PI } from './math.mjs';
console.log(multiply(4, 5)); // 20
console.log(add(10, 5)); // 15
console.log(PI); // 3.14159
// Importar todo
import * as math from './math.mjs';
console.log(math.add(2, 3)); // 5
```
### Habilitando ES Modules
**Opción 1: Usar extensión .mjs**
```javascript
// math.mjs
export const add = (a, b) => a + b;
```
**Opción 2: Agregar "type": "module" en package.json**
```json
{
"name": "mi-app",
"type": "module"
}
```
```javascript
// Ahora puedes usar .js con sintaxis ES
// math.js
export const add = (a, b) => a + b;
```
## Módulos Integrados
Node.js proporciona muchos módulos integrados útiles:
### fs (Sistema de Archivos)
```javascript
const fs = require('fs');
// Leer archivo
const data = fs.readFileSync('file.txt', 'utf8');
// Escribir archivo
fs.writeFileSync('output.txt', 'Hola, Mundo!');
// Asíncrono (recomendado)
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
```
### path (Manipulación de Rutas)
```javascript
const path = require('path');
// Unir rutas
const filePath = path.join(__dirname, 'data', 'users.json');
// /Users/usuario/proyecto/data/users.json
// Obtener extensión
const ext = path.extname('file.txt'); // .txt
// Obtener nombre de archivo
const filename = path.basename('/path/to/file.txt'); // file.txt
// Obtener directorio
const dir = path.dirname('/path/to/file.txt'); // /path/to
// Resolver ruta absoluta
const absolute = path.resolve('data', 'file.txt');
```
### http (Servidor HTTP)
```javascript
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('
¡Hola, Mundo!
');
});
server.listen(3000);
```
### os (Información del Sistema Operativo)
```javascript
const os = require('os');
console.log('Plataforma:', os.platform()); // darwin, win32, linux
console.log('CPUs:', os.cpus().length);
console.log('Memoria Total:', os.totalmem() / 1024 / 1024 / 1024, 'GB');
console.log('Memoria Libre:', os.freemem() / 1024 / 1024 / 1024, 'GB');
console.log('Directorio Home:', os.homedir());
```
### url (Análisis de URLs)
```javascript
const url = require('url');
const myUrl = new URL('https://ejemplo.com:8080/ruta?nombre=juan&edad=30');
console.log(myUrl.hostname); // ejemplo.com
console.log(myUrl.pathname); // /ruta
console.log(myUrl.search); // ?nombre=juan&edad=30
console.log(myUrl.searchParams.get('nombre')); // juan
```
### Módulos Integrados Comunes
| Módulo | Propósito |
|--------|----------|
| `fs` | Operaciones de sistema de archivos |
| `path` | Manipulación de rutas de archivos |
| `http`/`https` | Crear servidores/clientes HTTP |
| `os` | Información del sistema operativo |
| `events` | Emisor de eventos |
| `crypto` | Funciones criptográficas |
| `stream` | Datos de streaming |
| `util` | Funciones de utilidad |
## NPM (Node Package Manager)
NPM es el registro de paquetes más grande del mundo con más de 2 millones de paquetes.
### Inicializando un Proyecto
```bash
# Crear package.json
npm init
# Crear con valores por defecto
npm init -y
```
### package.json
```json
{
"name": "mi-aplicacion",
"version": "1.0.0",
"description": "Mi aplicación Node.js increíble",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"keywords": ["node", "express"],
"author": "Tu Nombre",
"license": "MIT",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
```
### Instalando Paquetes
```bash
# Instalar paquete (guardado en dependencias)
npm install express
npm i express # forma corta
# Instalar dependencia de desarrollo
npm install --save-dev nodemon
npm i -D nodemon # forma corta
# Instalar versión específica
npm install express@4.18.2
# Instalar globalmente
npm install -g typescript
# Instalar desde package.json
npm install
```
### Usando Paquetes
```javascript
// Importar paquete instalado
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/', (req, res) => {
res.send('¡Hola desde Express!');
});
app.listen(3000);
```
### Scripts de NPM
Define scripts personalizados en package.json:
```json
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"build": "tsc",
"test": "jest",
"lint": "eslint ."
}
}
```
```bash
# Ejecutar scripts
npm start
npm run dev
npm test # forma corta para npm run test
```
### Comandos Útiles de NPM
```bash
# Listar paquetes instalados
npm list
npm list --depth=0 # Solo nivel superior
# Ver paquete desactualizado
npm outdated
# Actualizar paquetes
npm update
npm update express # Actualizar paquete específico
# Desinstalar paquete
npm uninstall express
npm un express # forma corta
# Ver información del paquete
npm view express
npm view express version
# Buscar paquetes
npm search "http server"
# Limpiar caché
npm cache clean --force
```
### Versionamiento Semántico
NPM usa [Semver](https://semver.org/) para versiones de paquetes:
```
MAJOR.MINOR.PATCH
1 . 2 . 3
```
- **MAJOR**: Cambios que rompen compatibilidad (1.0.0 → 2.0.0)
- **MINOR**: Nuevas características compatibles (1.0.0 → 1.1.0)
- **PATCH**: Correcciones de errores (1.0.0 → 1.0.1)
### Símbolos de Versión
```json
{
"dependencies": {
"express": "4.18.2", // Versión exacta
"lodash": "^4.17.21", // Compatible (4.x.x)
"axios": "~1.4.0", // Aproximadamente (1.4.x)
"dotenv": "*", // Cualquier versión (no recomendado)
"mongoose": ">=6.0.0" // Mayor o igual
}
}
```
- **^** (Caret): Permite cambios que no modifican el primer dígito distinto de cero
- **~** (Tilde): Permite cambios de parche
## package-lock.json
Bloquea las versiones exactas de las dependencias para instalaciones consistentes:
```json
{
"name": "mi-app",
"version": "1.0.0",
"lockfileVersion": 3,
"packages": {
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-..."
}
}
}
```
**Siempre incluye package-lock.json en control de versiones!**
## Paquetes Populares
| Paquete | Propósito | Instalación |
|---------|-----------|-------------|
| **express** | Framework web | `npm i express` |
| **axios** | Cliente HTTP | `npm i axios` |
| **lodash** | Funciones de utilidad | `npm i lodash` |
| **dotenv** | Variables de entorno | `npm i dotenv` |
| **mongoose** | MongoDB ODM | `npm i mongoose` |
| **nodemon** | Recarga automática | `npm i -D nodemon` |
| **jest** | Framework de testing | `npm i -D jest` |
| **eslint** | Linter de código | `npm i -D eslint` |
## Ejemplo de Proyecto
Vamos a crear un proyecto completo:
### 1. Inicializar Proyecto
```bash
mkdir mi-app
cd mi-app
npm init -y
```
### 2. Instalar Dependencias
```bash
npm install express dotenv
npm install -D nodemon
```
### 3. Crear Archivos
**Archivo: .env**
```
PORT=3000
NODE_ENV=development
```
**Archivo: server.js**
```javascript
require('dotenv').config();
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(express.json());
// Rutas
app.get('/', (req, res) => {
res.json({ mensaje: '¡Hola desde Express!' });
});
app.get('/api/status', (req, res) => {
res.json({
status: 'OK',
entorno: process.env.NODE_ENV,
timestamp: new Date()
});
});
// Iniciar servidor
app.listen(PORT, () => {
console.log(`Servidor ejecutándose en http://localhost:${PORT}`);
});
```
### 4. Configurar Scripts
**Archivo: package.json**
```json
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
}
```
### 5. Ejecutar
```bash
# Desarrollo (con recarga automática)
npm run dev
# Producción
npm start
```
## Mejores Prácticas
1. **Usar package-lock.json**: Incluir en control de versiones
2. **Variables de Entorno**: Usar .env para configuración
3. **Versionamiento Semántico**: Seguir convenciones semver
4. **DevDependencies vs Dependencies**: Separar correctamente
5. **.gitignore**: Excluir node_modules del control de versiones
6. **Auditoría de Seguridad**: Ejecutar `npm audit` regularmente
7. **Mantener Actualizado**: Actualizar dependencias regularmente
## Recursos
- [Documentación de NPM](https://docs.npmjs.com/)
- [Node.js Módulos](https://nodejs.org/docs/latest/api/modules.html)
- [Versionamiento Semántico](https://semver.org/)
¡Domina el sistema de módulos de Node.js y NPM! 📦