⚔️ npm: El Arsenal Oficial del Ninja JavaScript

“El maestro no necesita todas las espadas del mundo. Solo aquellas que domina a la perfección.” - Código del Arsenal Ninja

🎯 ¿Qué es npm y por qué importa?

npm (Node Package Manager) es el gestor de paquetes más grande del mundo:

  • Más de 2.5 millones de paquetes disponibles
  • Viene pre-instalado con Node.js
  • Usado por millones de desarrolladores diariamente
  • Ecosistema estándar para JavaScript/TypeScript

Instalación:

# npm viene con Node.js. Descarga Node desde:
# https://nodejs.org/

# Verifica la instalación
node --version   # v20.11.0 (o superior)
npm --version    # 10.2.4 (o superior)

📜 El Corazón: package.json

El archivo package.json es el manifiesto de tu proyecto. Contiene:

  • Nombre y versión del proyecto
  • Dependencias (librerías que necesitas)
  • Scripts ejecutables
  • Metadatos (autor, licencia, repositorio)

Crear un package.json

Método interactivo:

npm init
# Te preguntará: nombre, versión, descripción, etc.

Método rápido (con valores por defecto):

npm init -y

Resultado:

{
  "name": "mi-proyecto-ninja",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

📦 Instalar Paquetes

Instalación Local (en el Proyecto)

# Sintaxis básica
npm install <paquete>

# Ejemplo real
npm install express

# Atajo (funciona igual)
npm i express

Qué sucede:

  1. npm descarga express desde npmjs.com
  2. Lo guarda en node_modules/express/
  3. Actualiza package.json agregando:
    "dependencies": {
      "express": "^4.18.2"
    }
  4. Crea/actualiza package-lock.json (versiones exactas)

Dependencias vs DevDependencies

Dependencies (producción): Librerías que tu aplicación necesita para funcionar en producción.

npm install react axios lodash

Se agregan a package.json bajo dependencies.

DevDependencies (desarrollo): Herramientas que solo necesitas en desarrollo (testing, linters, bundlers).

npm install --save-dev jest eslint webpack
# o atajo:
npm i -D jest eslint webpack

Se agregan a package.json bajo devDependencies.

Ejemplo de package.json completo:

{
  "name": "app-ninja",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2",
    "react": "^18.2.0"
  },
  "devDependencies": {
    "jest": "^29.5.0",
    "eslint": "^8.40.0"
  }
}

¿Por qué separarlas?

Cuando despliegas a producción, puedes instalar SOLO las dependencias necesarias:

npm install --production
# Instala solo dependencies, ignora devDependencies

Esto reduce tamaño y tiempo de instalación.


🔢 Versionado Semántico (Semver)

npm usa Semantic Versioning (Semver): MAJOR.MINOR.PATCH

Ejemplo: 4.18.2

  • 4 (MAJOR): Cambios incompatibles con versiones anteriores
  • 18 (MINOR): Nueva funcionalidad compatible hacia atrás
  • 2 (PATCH): Correcciones de bugs

Rangos de Versiones

{
  "dependencies": {
    "express": "4.18.2",     // Versión exacta
    "react": "^18.2.0",      // Compatible con minor/patch (18.x.x)
    "lodash": "~4.17.21",    // Compatible solo con patch (4.17.x)
    "axios": "*",            // Cualquier versión (¡peligroso!)
    "vue": ">=3.0.0 <4.0.0"  // Rango específico
  }
}

Recomendación ninja: Usa ^ (caret) para la mayoría de paquetes. Es el balance entre estabilidad y actualizaciones.


⚡ Scripts de npm

Los scripts son comandos personalizados que defines en package.json.

Scripts Comunes

{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack --mode production",
    "test": "jest",
    "lint": "eslint src/",
    "format": "prettier --write ."
  }
}

Ejecutar un script:

npm run dev
npm run build
npm run test

# Scripts especiales no necesitan 'run':
npm start
npm test

Scripts Útiles para Proyectos Reales

{
  "scripts": {
    // Desarrollo
    "dev": "vite",
    "dev:api": "nodemon server.js",

    // Build
    "build": "vite build",
    "build:prod": "NODE_ENV=production vite build",

    // Testing
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",

    // Calidad de código
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css}\"",

    // Deployment
    "deploy": "npm run build && firebase deploy",

    // Otros
    "clean": "rm -rf node_modules dist",
    "reinstall": "npm run clean && npm install"
  }
}

🔍 Comandos Esenciales de npm

Ver Paquetes Instalados

# Lista todos los paquetes (árbol completo)
npm list

# Solo dependencias directas (nivel 0)
npm list --depth=0

# Verificar versión de un paquete específico
npm list express

Actualizar Paquetes

# Ver paquetes desactualizados
npm outdated

# Actualizar TODOS los paquetes (respetando rangos en package.json)
npm update

# Actualizar un paquete específico
npm update express

# Instalar última versión (ignora rangos)
npm install express@latest

Desinstalar Paquetes

# Desinstalar y eliminar de package.json
npm uninstall lodash

# Atajo
npm un lodash
npm remove lodash
npm rm lodash

Limpiar Caché

# Si npm se comporta extraño, limpia su caché
npm cache clean --force

Auditar Seguridad

# Revisar vulnerabilidades de seguridad
npm audit

# Intentar arreglarlas automáticamente
npm audit fix

# Forzar correcciones (puede romper compatibilidad)
npm audit fix --force

🌍 Instalación Global

Algunos paquetes se instalan globalmente para usar como comandos CLI en cualquier proyecto.

# Instalar globalmente
npm install -g typescript

# Ahora puedes usar 'tsc' en cualquier directorio
tsc --version

Cuándo instalar globalmente:

SÍ instala global:

  • typescript - Compilador de TypeScript
  • nodemon - Auto-reinicia servidor en desarrollo
  • eslint - Linter de código
  • create-react-app - Generador de proyectos React
  • vercel - CLI de despliegue

NO instales global:

  • Librerías del proyecto (react, express, lodash)
  • Dependencias que cambian por proyecto

Problema del global: Si dos proyectos necesitan versiones diferentes de TypeScript, solo puedes tener una instalada globalmente.

Solución ninja: Usa npx (próximo tema).


🎯 Flujo de Trabajo Real

Proyecto Nuevo

# 1. Crear directorio
mkdir mi-proyecto
cd mi-proyecto

# 2. Inicializar npm
npm init -y

# 3. Instalar dependencias
npm install express
npm install -D nodemon eslint

# 4. Crear .gitignore
echo "node_modules/" > .gitignore

# 5. Configurar scripts
# (Editar package.json manualmente)

# 6. Inicializar Git
git init
git add .
git commit -m "feat: inicializar proyecto"

Clonar Proyecto Existente

# 1. Clonar repositorio
git clone https://github.com/usuario/proyecto.git
cd proyecto

# 2. Instalar dependencias (lee package.json)
npm install

# 3. Ejecutar en desarrollo
npm run dev

⚠️ NUNCA subas node_modules/ a Git:

Otros desarrolladores ejecutarán npm install para recrear la carpeta.


💡 Jutsu Secreto: package-lock.json

El archivo package-lock.json registra las versiones exactas de TODAS las dependencias (incluyendo sub-dependencias).

Por qué existe:

// package.json (rangos)
{
  "dependencies": {
    "express": "^4.18.0"
  }
}

El ^ permite instalar 4.18.0, 4.18.1, 4.19.0, etc.

Problema: Si instalas hoy y tu compañero instala mañana (después de que salió 4.19.0), tendrán versiones diferentes.

Solución: package-lock.json fija versiones exactas:

{
  "express": {
    "version": "4.18.2",  // ← Versión exacta instalada
    "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
    "integrity": "sha512-..."
  }
}

Reglas de oro:

  • ✅ SÍ versiona package-lock.json en Git
  • ✅ Ejecuta npm ci en CI/CD en lugar de npm install
  • ❌ NO lo edites manualmente
  • ❌ NO lo borres (a menos que estés resolviendo conflictos)

⚠️ Errores Comunes

Error #1: Módulo no encontrado

Error: Cannot find module 'express'

Causa: Falta ejecutar npm install

Solución:

npm install

Error #2: Versiones incompatibles

npm ERR! peer dep missing: react@^18.0.0

Causa: Una librería requiere una versión específica de otra.

Solución:

# Instalar versión correcta
npm install react@18.0.0

Error #3: Permisos en instalación global (Linux/Mac)

npm ERR! Error: EACCES: permission denied

Causa: Intentas instalar globalmente sin permisos.

Solución:

# Opción 1: Usar npx en lugar de global
npx create-react-app mi-app

# Opción 2: Configurar directorio npm sin sudo
# (Busca "npm without sudo" en Google)

🎯 Reto Ninja del Tema

Misión: Crear un proyecto completo con npm

  1. Inicializa un proyecto:

    mkdir ninja-api
    cd ninja-api
    npm init -y
  2. Instala dependencias:

    npm install express
    npm install -D nodemon
  3. Crea un archivo index.js:

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
      res.json({ mensaje: 'Bienvenido ninja' });
    });
    
    app.listen(3000, () => {
      console.log('Servidor en http://localhost:3000');
    });
  4. Añade scripts en package.json:

    "scripts": {
      "start": "node index.js",
      "dev": "nodemon index.js"
    }
  5. Ejecuta:

    npm run dev
  6. Verifica en navegador: http://localhost:3000

Criterios de éxito:

  • ✅ El servidor responde con JSON
  • nodemon reinicia automáticamente al editar código
  • ✅ Tienes .gitignore con node_modules/
  • package-lock.json está versionado

📚 Recursos Adicionales


Siguiente Pergamino: 4.3 npx: El Jutsu Temporal

¿Creaste tu primera API? Comparte tu código en Discord con #npmNinja! ⚔️🥷