Scripts de package.json
Los scripts de ciclo de vida de npm automatizan los pasos de construcción, prueba y publicación. Son el contrato entre desarrolladores, CI y pipelines de despliegue.
Receta
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.build.json",
"start": "node dist/index.js",
"test": "node --import tsx --test test/**/*.test.ts",
"typecheck": "tsc --noEmit",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run typecheck"
}
}Cuándo usarlo:
- Necesitas un comando (
npm test) que funcione localmente y en CI. - Las instalaciones de Git o
npm publishdeben compilar TypeScript antes de que los consumidores importen el paquete. - Quieres barreras de seguridad que bloqueen publicaciones rotas sin tener que recordar pasos manuales.
Ejemplo de trabajo
{
"name": "@acme/billing-api",
"version": "1.4.0",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": ["dist"],
"scripts": {
"dev": "tsx watch src/server.ts",
"build": "tsc -p tsconfig.build.json",
"start": "node dist/server.js",
"test": "node --import tsx --test",
"typecheck": "tsc --noEmit",
"lint": "eslint .",
"prepare": "npm run build",
"prepublishOnly": "npm run lint && npm test && npm run typecheck",
"postversion": "git push && git push --tags"
}
}# Desarrollo local
npm run dev
# Pipeline de CI (mismos puntos de entrada)
npm ci
npm run lint
npm run typecheck
npm test
npm run buildLo que esto demuestra:
devusatsx watchpara una rápida iteración de TypeScript sin un paso de compilación separado.preparese construye ennpm installcuando el paquete se instala desde git o un tarball empaquetado.prepublishOnlyse ejecuta solo antes denpm publish, detectando regresiones antes de que lleguen al registro.postversionautomatiza los pushes de etiquetas después denpm version patch.
Análisis profundo
Cómo funciona
- npm ejecuta scripts por nombre:
npm run <script>onpm testpara el aliastest. - Los hooks de ciclo de vida (
prepare,prepublishOnly,postinstall) se disparan automáticamente en momentos definidos. - Los scripts heredan
PATHconnode_modules/.binantepuesto, por lo que los CLIs locales se resuelven sinnpx. npm runestablecenpm_lifecycle_eventpara que los scripts puedan ramificarse en el hook que los activó.
Hooks de ciclo de vida comunes
| Hook | Cuándo se ejecuta | Uso típico |
|---|---|---|
prepare | Después de npm install (local y empaquetado) | Compilar TypeScript, generar tipos |
prepublishOnly | Antes de npm publish | Pruebas, lint, verificación de construcción |
postinstall | Después de la instalación de dependencias | Construcciones de complementos nativos (usar con moderación) |
preversion / postversion | Alrededor de npm version | Changelog, push de etiquetas git |
Notas de TypeScript
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.build.json",
"typecheck": "tsc --noEmit -p tsconfig.json"
}
}- Mantén
typecheckseparado debuildpara que CI pueda fallar rápidamente sin emitirdist/. - Usa
tsxpara el desarrollo; envía JS compilado endist/para producciónnode dist/....
Errores comunes
- Bucles infinitos de prepare -
preparellamando anpm installo reinstalando se activa a sí mismo. Solución: solo compila o copia archivos enprepare. - Postinstall pesado - Las instalaciones lentas frustran a todos los desarrolladores y trabajos de CI. Solución: mueve la configuración opcional a un
npm run setupdocumentado. - Omitir pruebas en la publicación -
npm publish --ignore-scriptsomiteprepublishOnly. Solución: fuerza la publicación de CI desde commits etiquetados con comprobaciones de scripts. - Variables de entorno multiplataforma -
NODE_ENV=production cmdfalla en shells de Windows. Solución: usacross-envo banderas específicas del framework. - Prepare implícito en dependencias de git - La instalación desde GitHub ejecuta
prepare, lo que puede sorprender a los consumidores. Solución: publica artefactos precompilados en npm en lugar de URLs de git para bibliotecas.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
Makefile / just | Repositorios políglotas, flujos de trabajo pesados en operaciones | El equipo espera npm test en todas partes |
| Pipeline de tareas de Turborepo | Monorepos con build/test en caché | Servicio API de un solo paquete |
| Husky + lint-staged | Solo formato pre-commit | Reemplazar completamente las puertas de CI |
Preguntas frecuentes
¿Cuál es la diferencia entre prepare y prepublishOnly?
preparese ejecuta ennpm install(incluidas las dependencias de git) y antes de empaquetar/publicar.prepublishOnlyse ejecuta solo inmediatamente antes denpm publish.- Usa
preparepara las construcciones que los consumidores necesitan; usaprepublishOnlypara las comprobaciones solo de publicación.
¿Puedo ejecutar varios comandos en un solo script?
{
"scripts": {
"check": "npm run lint && npm run typecheck && npm test"
}
}Encadena con && para que los pasos posteriores se salten si un paso anterior falla.
¿Cómo paso argumentos a un script?
npm test -- --grep "billing"Los argumentos después de -- se reenvían al comando subyacente.
¿Debería start ejecutar tsx o JS compilado?
startde producción debe ejecutarnode dist/...después debuild.- El desarrollo usa
tsx watcha través de un scriptdevseparado.
¿Por qué npm ejecuta build en npm install en mi biblioteca?
prepare se ejecuta después de la instalación cuando el paquete se instala desde git o una ruta local. Publica dist/ compilado en npm o documenta el paso de compilación.
¿Cómo silencio la salida del ciclo de vida en CI?
Usa --ignore-scripts solo cuando controles completamente lo que se omite. Prefiere npm run build explícito en CI en lugar de depender de efectos secundarios.
¿Pueden los scripts llamar a otros scripts del paquete?
Sí: "check": "npm run lint && npm run test". npm resuelve los binarios locales automáticamente.
¿Qué se ejecuta antes de npm version?
preversion (opcional), luego el incremento de versión, luego postversion. Usa postversion para empujar etiquetas.
¿Debo usar npx dentro de los scripts?
Prefiere las devDependencies (tsx, eslint) y los nombres de comandos simples (tsx, eslint) para que las versiones estén fijadas en el lockfile.
¿Cómo organizan los monorepos los scripts?
El package.json raíz delega: "test": "turbo run test". Cada espacio de trabajo mantiene sus propios scripts build/test.
Relacionado
- Lockfiles e instalaciones reproducibles - CI usa la misma ruta de instalación
- Publicación en npm - semver e higiene de publicación
- Conceptos básicos de los gestores de paquetes - selección del gestor
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.