Esta guía configura un entorno de Node.js con TypeScript utilizando "type": "module" (import/export nativos).
Antes de instalar dependencias, asegúrate de que tu package.json tenga la propiedad type configurada. Si acabas de iniciar el proyecto (npm init -y), agrega esta línea manualmente:
{
"type": "module"
}npm i -D typescript @types/node ts-node nodemon rimrafGenera el archivo tsconfig.json:
npx tsc --init --outDir dist/ --rootDir srcImportante: Edita el tsconfig.json para soportar módulos nativos. Busca y modifica (o añade) estas opciones:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext", /* Crucial para type: module */
"moduleResolution": "NodeNext", /* Crucial para type: module */
"outDir": "./dist",
"rootDir": "./src",
"esModuleInterop": true,
"strict": true
},
"ts-node": {
"esm": true /* Habilita modo ESM en ts-node */
}
}Este archivo configura cómo nodemon debe vigilar los cambios.
{
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "npx ts-node-esm ./src/app.ts"
}Agrega estos scripts a tu package.json. Aquí definimos dos formas de correr el entorno de desarrollo:
"scripts": {
"dev": "ts-node src/app.ts",
"dev:nodemon": "nodemon",
"build": "rimraf ./dist && tsc",
"start": "npm run build && node dist/app.js"
}Nota: Si el script
"dev"te da error de módulos, cámbialo por"ts-node-esm src/app.ts".
npm run dev (Ejecución directa)
- Qué hace: Ejecuta tu código una sola vez usando
ts-nodey termina el proceso cuando el programa acaba (o si hay un error). - Cuándo usarlo: Ideal para verificar rápidamente si el código compila y funciona, para correr scripts de mantenimiento, migraciones de base de datos, o depuración (debugging) puntual donde no quieres que la consola se limpie sola.
npm run dev:nodemon (Modo Watch)
- Qué hace: Ejecuta el comando
nodemon, el cual lee la configuración denodemon.json. Mantiene el proceso vivo y reinicia automáticamente el servidor cada vez que guardas un cambio en un archivo. - Cuándo usarlo: Es el estándar para el desarrollo diario de servidores (Express, Fastify, etc.), ya que te ahorra tener que detener y arrancar el servidor manualmente con cada cambio de código.
Al usar type: "module", Node requiere que las importaciones de archivos locales incluyan la extensión .js.
Correcto:
import { miFuncion } from './utils.js';Incorrecto:
import { miFuncion } from './utils';