📋 package.json: El Manifiesto del Proyecto y Versionado Semántico
“El pergamino del shinobi no solo describe sus técnicas, también establece las reglas para invocarlas.” - Código del Manifiesto Ninja
🎯 ¿Qué es package.json?
El archivo package.json es el corazón de todo proyecto JavaScript/Node.js:
- Define metadatos del proyecto (nombre, versión, autor)
- Lista dependencias (librerías que necesitas)
- Configura scripts ejecutables
- Establece reglas de versionado
- Configura herramientas (ESLint, Babel, Jest)
Sin package.json:
- No puedes instalar dependencias con npm
- No hay forma de compartir tu proyecto
- Cada desarrollador configura todo manualmente
📜 Anatomía Completa de package.json
{
// ========== METADATOS ==========
"name": "ninja-app",
"version": "1.2.3",
"description": "Aplicación ninja para gestionar misiones",
"keywords": ["ninja", "missions", "tasks"],
"author": "Abraham Pech <abraham@8devmx.com>",
"license": "MIT",
"homepage": "https://github.com/usuario/ninja-app#readme",
"repository": {
"type": "git",
"url": "https://github.com/usuario/ninja-app.git"
},
"bugs": {
"url": "https://github.com/usuario/ninja-app/issues"
},
// ========== PUNTO DE ENTRADA ==========
"main": "index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
// ========== SCRIPTS ==========
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "jest",
"lint": "eslint src/",
"format": "prettier --write ."
},
// ========== DEPENDENCIAS ==========
"dependencies": {
"express": "^4.18.2",
"react": "^18.2.0"
},
"devDependencies": {
"jest": "^29.5.0",
"eslint": "^8.40.0"
},
"peerDependencies": {
"react": "^18.0.0"
},
// ========== CONFIGURACIÓN ==========
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
},
"private": false,
"type": "module"
}
🎯 Campos Esenciales
1. name (Obligatorio)
El nombre del paquete. Debe ser único en npm si planeas publicarlo.
Reglas:
- Minúsculas
- Sin espacios (usa
-o_) - Máximo 214 caracteres
{
"name": "mi-libreria-ninja" // ✅ Correcto
"name": "Mi Librería" // ❌ Espacios y mayúsculas
"name": "@8devmx/utils" // ✅ Scoped package (organización)
}
2. version (Obligatorio)
Versión del proyecto usando Semantic Versioning.
{
"version": "1.2.3"
// MAJOR.MINOR.PATCH
}
3. description
Breve descripción que aparece en npm search.
{
"description": "Librería para autenticación ninja con JWT"
}
4. main
Archivo principal que se carga cuando alguien hace require('tu-paquete').
{
"main": "index.js", // CommonJS
"module": "index.esm.js", // ES Modules (para bundlers)
"types": "index.d.ts" // TypeScript definitions
}
5. scripts
Comandos personalizados ejecutables con npm run.
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"build": "webpack --mode production",
"test": "jest --coverage"
}
}
🚀 Scripts Poderosos
Scripts Pre y Post
npm ejecuta automáticamente scripts pre y post:
{
"scripts": {
"prebuild": "npm run lint", // Se ejecuta ANTES de build
"build": "webpack",
"postbuild": "npm run deploy", // Se ejecuta DESPUÉS de build
"pretest": "npm run compile",
"test": "jest",
"posttest": "npm run coverage"
}
}
Ejecutas:
npm run build
Sucede:
# 1. npm run prebuild (lint)
# 2. npm run build (webpack)
# 3. npm run postbuild (deploy)
Scripts Útiles para Proyectos Reales
{
"scripts": {
// Desarrollo
"dev": "vite --port 3000",
"dev:api": "nodemon --watch src src/server.js",
"dev:db": "docker-compose up -d postgres",
// Build
"build": "tsc && vite build",
"build:analyze": "vite build --mode analyze",
"build:clean": "rm -rf dist && npm run build",
// Testing
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:e2e": "playwright test",
// Calidad de código
"lint": "eslint src/**/*.{js,ts,jsx,tsx}",
"lint:fix": "eslint src/**/*.{js,ts,jsx,tsx} --fix",
"format": "prettier --write \"src/**/*.{js,ts,jsx,tsx,json,css,md}\"",
"type-check": "tsc --noEmit",
// Deployment
"predeploy": "npm run build",
"deploy": "vercel --prod",
// Utilidades
"clean": "rm -rf node_modules dist .next",
"reinstall": "npm run clean && npm install",
"prepare": "husky install" // Git hooks
}
}
Pasar Argumentos a Scripts
{
"scripts": {
"test": "jest"
}
}
# Pasar flags después de --
npm run test -- --coverage
# Ejecuta: jest --coverage
Ejecutar Múltiples Scripts en Paralelo
# Instalar npm-run-all
npm install -D npm-run-all
{
"scripts": {
"dev:client": "vite",
"dev:server": "nodemon server.js",
"dev": "npm-run-all --parallel dev:client dev:server"
}
}
🔢 Versionado Semántico (Semver)
Estructura: MAJOR.MINOR.PATCH
Ejemplo: 2.5.7
- 2 (MAJOR): Cambios incompatibles con versiones anteriores
- 5 (MINOR): Nueva funcionalidad compatible hacia atrás
- 7 (PATCH): Correcciones de bugs
Cuándo Incrementar Cada Número
# PATCH (1.0.0 → 1.0.1)
- Correcciones de bugs
- Optimizaciones de rendimiento
- Cambios en documentación
# MINOR (1.0.1 → 1.1.0)
- Nueva funcionalidad compatible
- Deprecar funciones (aún funcionan)
- Mejoras significativas
# MAJOR (1.1.0 → 2.0.0)
- Cambios incompatibles (breaking changes)
- Remover funciones deprecadas
- Cambiar APIs públicas
Rangos de Versiones
{
"dependencies": {
// Versión exacta
"express": "4.18.2",
// Caret (^): Compatible con minor/patch
"react": "^18.2.0",
// Permite: 18.2.0, 18.2.1, 18.3.0
// NO permite: 19.0.0
// Tilde (~): Compatible solo con patch
"lodash": "~4.17.21",
// Permite: 4.17.21, 4.17.22
// NO permite: 4.18.0
// Mayor o igual
"axios": ">=1.0.0",
// Rango específico
"vue": ">=3.0.0 <4.0.0",
// Cualquier versión (¡PELIGROSO!)
"cowsay": "*",
// Última versión
"typescript": "latest"
}
}
Operadores Comparados
// ^ (Caret) - Recomendado por defecto
"^1.2.3" → >=1.2.3 <2.0.0
"^0.2.3" → >=0.2.3 <0.3.0 (cuidado con 0.x)
"^0.0.3" → >=0.0.3 <0.0.4 (muy restrictivo)
// ~ (Tilde) - Para parches solamente
"~1.2.3" → >=1.2.3 <1.3.0
"~1.2" → >=1.2.0 <1.3.0
"~1" → >=1.0.0 <2.0.0
// Sin operador - Versión exacta
"1.2.3" → 1.2.3 (exactamente)
¿Cuál usar?
^(caret): Recomendado para la mayoría de paquetes~(tilde): Cuando quieres solo bugfixes- Exacta: Solo para paquetes críticos o problemáticos
🎯 Tipos de Dependencias
dependencies
Paquetes que tu aplicación necesita en producción.
{
"dependencies": {
"express": "^4.18.2",
"react": "^18.2.0",
"lodash": "^4.17.21"
}
}
devDependencies
Herramientas solo para desarrollo y testing.
{
"devDependencies": {
"jest": "^29.5.0",
"eslint": "^8.40.0",
"typescript": "^5.0.0",
"nodemon": "^2.0.22"
}
}
peerDependencies
Especifica qué versiones de paquetes debe tener el usuario de tu librería.
// Tu librería: react-ninja-ui
{
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Significado: “Esta librería funciona con React 18+. El usuario debe instalarlo.”
optionalDependencies
Paquetes opcionales que no rompen la instalación si fallan.
{
"optionalDependencies": {
"fsevents": "^2.3.2" // Solo funciona en macOS
}
}
🛠️ Configuración Avanzada
Especificar Versión de Node.js
{
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
}
}
npm avisará si el usuario tiene versión incorrecta.
Archivos a Publicar (si subes a npm)
{
"files": [
"dist/",
"README.md",
"LICENSE"
]
}
Solo estos archivos se subirán a npm (ignora src/, tests/, etc.).
Tipo de Módulo
{
// Para usar ES Modules (import/export)
"type": "module"
// Para CommonJS (require/module.exports) - default
"type": "commonjs"
}
Privado (no publicar en npm)
{
"private": true
}
Previene publicación accidental con npm publish.
💡 Buenas Prácticas
1. Usa ^ para Dependencias
{
"dependencies": {
"express": "^4.18.2" // ✅ Recibe bugfixes automáticamente
}
}
2. Separa Correctamente dependencies y devDependencies
# Dependencia de producción
npm install react
# Dependencia de desarrollo
npm install -D jest
3. Versiona package-lock.json
# .gitignore
node_modules/
# NO ignores package-lock.json (debe estar versionado)
4. Especifica Versión de Node.js
{
"engines": {
"node": ">=18.0.0"
}
}
5. Usa Scripts Descriptivos
{
"scripts": {
"dev": "vite", // ✅ Claro
"start:dev:server": "nodemon", // ❌ Muy largo
"s": "webpack", // ❌ Críptico
}
}
🎯 Reto Ninja del Tema
Misión: Crear un package.json profesional
-
Inicializa proyecto:
mkdir ninja-manifest cd ninja-manifest npm init -y -
Edita
package.jsoncon estos campos:{ "name": "ninja-tasks", "version": "0.1.0", "description": "Gestor de misiones ninja", "author": "Tu Nombre", "license": "MIT", "scripts": { "start": "node index.js", "dev": "nodemon index.js", "test": "echo \"No tests yet\"", "prebuild": "echo \"Limpiando...\"", "build": "echo \"Building...\"", "postbuild": "echo \"Build completo\"" }, "dependencies": { "express": "^4.18.2" }, "devDependencies": { "nodemon": "^2.0.22" }, "engines": { "node": ">=18.0.0" } } -
Instala:
npm install -
Prueba scripts:
npm run build # Verifica pre/post hooks npm run dev # Nodemon debería funcionar
Criterios de éxito:
- ✅ Todos los campos obligatorios presentes
- ✅ Scripts pre/post funcionan
- ✅ Dependencias instaladas correctamente
- ✅ Usaste
^en versiones
📚 Recursos Adicionales
Siguiente Pergamino: 4.8 Lockfiles y Reproducibilidad
¿Creaste tu manifiesto? Comparte tu package.json en Discord con #ManifiestoNinja! 📋🥷