Aprende, paso a paso y con buenas prácticas, a crear tu primer programa en Node.js que recibe argumentos por terminal, valida rangos y genera un número aleatorio. Verás cómo organizar el espacio de trabajo, iniciar git y configurar npm con seguridad y claridad.
¿Cómo preparar el entorno de Node.js y el espacio de trabajo?
Tener un entorno ordenado acelera el desarrollo. Necesitas una terminal, un editor de código y una carpeta para tus proyectos. Se recomienda crear una carpeta de trabajo (por ejemplo, dev) y clasificar proyectos: de trabajo, personales o de pruebas puntuales. Así mantienes control y contexto.
¿Por qué usar Git desde el inicio?
Ejecuta git init para guardar el historial local de cambios.
No obliga a subir a GitHub o BitBucket.
Ayuda a recordar qué cambió, cuándo y por qué.
¿Cómo organizar la carpeta del proyecto?
Crea la carpeta del proyecto: mkdir nodejs.
Entra en la carpeta y abre el editor: code . en Visual Studio Code.
Crea la estructura base: carpeta src y archivo src/index.js.
¿Cómo inicializar npm y configurar el proyecto?
Inicializa el proyecto con npm init. Responde a las indicaciones para definir metadatos y el punto de entrada.
¿Qué datos define npm init?
Nombre: toma el de la carpeta automáticamente.
Versión: 1.0 por defecto.
Descripción: “Node.js examples”.
Punto de entrada: index.js.
Scripts de prueba: por ahora ninguno.
Repositorio: omite si no usarás un remoto.
Palabras clave: opcional por ahora.
Autor: “Óscar Barajas” con correo.
Licencia: MIT para permitir uso, distribución y ventas.
¿Cómo crear un generador de números aleatorios con argumentos en Node.js?
El programa genera un número aleatorio entre 1 y 100 si no recibe argumentos. Si le pasas dos valores por terminal, usa ese rango mínimo y máximo. Incluye validaciones para evitar errores por entradas inválidas.
¿Cómo capturar y validar argumentos por terminal?
Captura argumentos reales a partir de la tercera posición: process.argv.slice(2).
Define valores por defecto: min = 1 y max = 100.
Si hay al menos dos argumentos, conviértelos con parseInt en base 10.
Valida que no sean NaN y que min < max.
Si el rango no es válido, muestra un mensaje y usa los valores por defecto.
// src/index.jsconst args = process.argv.slice(2);let min =1;let max =100;if(args.length>=2){const parseMin =parseInt(args[0],10);const parseMax =parseInt(args[1],10);if(!isNaN(parseMin)&&!isNaN(parseMax)&& parseMin < parseMax){ min = parseMin; max = parseMax;}else{console.log('rango inválido: usando valores por defecto del 1 al 100.');}}const randomNumber =Math.floor(Math.random()*(max - min +1))+ min;console.log(`número aleatorio generado entre ${min} y ${max}: ${randomNumber}`);
Habilidades y conceptos que aplicas:
Uso de process.argv y slice(2) para leer argumentos reales.
Valores por defecto y reasignación controlada con let.
Conversión numérica con parseInt y base 10.
Validaciones con isNaN y comparación de rangos (min < max).
Manejo de errores de usuario con mensajes claros.
¿Cómo generar un número aleatorio inclusivo?
Fórmula clave: Math.floor(Math.random() * (max - min + 1)) + min.
Math.random genera [0, 1), sin incluir 1.
Al multiplicar por (max - min + 1) y sumar min, aseguras incluir ambos extremos del rango.
¿Cómo ejecutar y depurar en la terminal?
Ejecutar sin argumentos: node src/index.js.
Ejecutar con rango: node src/index.js 10 50.
Entradas inválidas (por ejemplo, “hola” 20): muestra “rango inválido” y usa 1–100.
Si aparece un error, lee el mensaje: por ejemplo, confundir process.args con process.argv impide usar slice. Los errores señalan dónde corregir.
¿Te animas a mejorar la validación? Propón cómo evitar imprimir un aleatorio cuando el rango sea inválido y cuéntalo en los comentarios.
Yo utilizo Warp.dev como terminal, ya que incorpora AI, y VSCode con GitHub Copilot y Cursor AI para programar.
const args = process.argv.slice(2);try{let min = args[0]?Number(args[0]):1;let max = args[1]?Number(args[1]):100;if(isNaN(min)||isNaN(max))thrownewError("Invalid arguments. Please provide two numbers.");if(min > max)thrownewError("Minimum value cannot be greater than maximum value.");if(min <0|| max <0)thrownewError("Negative numbers are not allowed.");const randomNumber =Math.floor(Math.random()*(max - min +1))+ min;console.log(`Random number between ${min} and ${max}: ${randomNumber}`);}catch(error){console.error(error); process.exit(1);}```const args = process.argv.slice(2);
try { let min = args\[0] ? Number(args\[0]) : 1; let max = args\[1] ? Number(args\[1]) : 100;
if (isNaN(min) || isNaN(max)) throw new Error("Invalid arguments. Please provide two numbers."); if (min > max) throw new Error("Minimum value cannot be greater than maximum value."); if (min < 0 || max < 0) throw new Error("Negative numbers are not allowed.");
const randomNumber = Math.floor(Math.random() \* (max - min + 1)) + min; console.log(`Random number between ${min} and ${max}: ${randomNumber}`);}catch(error){console.error(error); process.exit(1);}
tratando de superar al maestro, pillín
Super la solución, pero se pueden ahorrar muchas líneas de código solamente poniendo el process.exit(0) en el else después del console.log('⚠️ Rango Inválido.'); para dejar el código que llevábamos sin realizarle tantas modificaciones, pero muy buena solución 👍
Paso a paso y explicación de cómo obtener el array con los argumentos
que gran explicacion
Agreamos un return; despues del log de "Rango Invalido" y se detiene la ejecución
comparto la documentación sobre el método parseInt en JavaScript parseInt() - JavaScript | MDN
const args = process.argv.slice(2)let min =1let max =100constgetRandomNumber=(min, max)=>{const randomNumber =Math.floor(Math.random()*(max - min +1)+ min)console.log(`Numero aleatorio generado entre ${min} y ${max} es: ${randomNumber}`)}if(args.length>=2){// Recibo como stringconst parseMin =parseInt(args[0],10)//segundo parametro radix o base numerica (2, 8 16, 10) binario, octal, hexadecimal decimal etc...const parseMax =parseInt(args[1],10)// Si no es un numero Nan -> hola hola if(!isNaN(parseMin)&&!isNaN(parseMax)&& parseMin < parseMax){ min = parseMin; max = parseMax;getRandomNumber(min, max)}else{console.log('Rango invalido usando valores por defecto del 1 al 100')}}elseif(min < max){getRandomNumber(min, max)}
process.args es un arreglo que contiene los argumentos pasados al ejecutar el script desde la terminal.
slice(2) elimina los dos primeros elementos:
process.args[0]: ruta al ejecutable de Node.js.
process.args[1]: ruta al archivo que estás ejecutando.
Lo que queda son los argumentos personalizados que tú pasas
Solo le puse el return para que no devuelva el rango si se pasa un string por la terminal.
return console.log('Rango invalido. Usando valores por defecto del 1 - 100');
}
}
const randomNumber = Math.floor(Math.random()*(max - min + 1)) + min;
console.log(Numero aleatorio generado entre ${min} y ${max}: ${randomNumber});
¡Les dejo el código de la clase comentado! 🧑💻
Mi resultado:
hola, en mi caso tuve que hacer algunos cambios al código después del debugging, les comparto lo que hice por si a alguien más le sirve
const process =require('process')const args = process.argvtry{let min =1let max =100if(args.length>2){const parsedMin =parseInt(args[2])const parsedMax =parseInt(args[3])if(isNaN(parsedMin)||isNaN(parsedMax))thrownewError("¡Argumentos inválidos. Por favor, ingrese dos números!")if(parsedMin <0|| parsedMax <0)thrownewError("¡Números negativos no son permitidos!")if(parsedMin > parsedMax)thrownewError("¡El valor mínimo no puede ser mayor que el valor máximo!") min = parsedMin
max = parsedMax
}const randomNumber =Math.floor(Math.random()*(max - min +1))+ min
console.log(`Número aleatorio entre ${min} y ${max}: ${randomNumber}`)}catch(error){console.error(error) process.exit(1)}```*const* process = require('process')
*const* args = process.argv
try{
*let* min = 1 *let* max = 100
if(args.length > 2){ *const* parsedMin = parseInt(args\[2]) *const* parsedMax = parseInt(args\[3])
if(isNaN(parsedMin) || isNaN(parsedMax)) throw new Error("¡Argumentos inválidos. Por favor, ingrese dos números!") if(parsedMin < 0 || parsedMax < 0) throw new Error("¡Números negativos no son permitidos!") if (parsedMin > parsedMax) throw new Error("¡El valor mínimo no puede ser mayor que el valor máximo!")
min = parsedMin max = parsedMax }
*const* randomNumber = Math.floor(Math.random() \* (max - min + 1)) + min
console.log(`Número aleatorio entre ${min} y ${max}: ${randomNumber}`)}catch(error){console.error(error) process.exit(1)}
¿Cuál es la diferencia entre args y argv?
Hola Jacobo. Mira, esto es más sencillo de lo que parece, no te enredes.
Cuando corres un programa con Node y le pasas palabras extra (como crear usuario), Node guarda absolutamente todo lo que escribiste en una lista larga que técnicamente se llama argv. Esa lista siempre trae un par de cosas "de relleno" en las primeras dos posiciones: la ruta de dónde está instalado Node y la ruta de tu propio archivo. Es como si te dieran la bolsa del súper con el ticket de compra y el panfleto de ofertas adentro, antes de que llegues a tus verduras.
Como a nosotros esas dos primeras cosas no nos interesan para que el programa funcione, lo que hacemos es sacarlas y quedarnos solo con lo que realmente escribimos con intención. A esa nueva lista, ya limpia y ordenada, por costumbre le ponemos el nombre args (que es simplemente una palabra corta para decir "argumentos").
En resumen:
argv es la lista cruda que te da el sistema, con los papelitos de más incluidos.
argses la lista que armas tú después de sacar esos papelitos, lista para usar sin estorbos.
Si imprimes argv sin limpiarla, verás rutas feas del sistema que confunden a cualquiera. Si imprimes args, verás justo lo que necesitas: crear usuario.
¿Lo ves? Uno es lo que te dan, el otro es lo que tú eliges usar. Fácil, ¿no?
Mi solucion:
Como configure type como module, tengo que usar process.exit, justamente en la proxima clase se enseña si es mejor ES Modules o CommonJS, asi que esta solucion es para un proyecto ES Modules
const args = process.argv.slice(2)let min =1let max =100if(args.length>=2){const parsedMin =parseInt(args[0],10);const parsedMax =parseInt(args[1],10);if(!isNaN(parsedMin)&&!isNaN(parsedMax)&& parsedMin < parsedMax ){ min = parsedMin; max = parsedMax;}else{console.log('Range invalid'); process.exit(1)}}const randomNum =Math.floor(Math.random()*(max - min +1))+ min;console.log(`Random number generated between ${min} y ${max}: ${randomNum}`)
Aqui esta mi solucion
const args = process.argv.slice(2);let min =1;let max =100;if(args.length>=2){const parseMin =parseInt(args[0],10);const parseMax =parseInt(args[1],10);if(!isNaN(parseMin)&&!isNaN(parseMax)&& parseMin < parseMax){ min = parseMin; max = parseMax;}else{console.log('⚠️ Rango Invalido');return;}}const randomNumer =Math.floor(Math.random()*(max - min +1))+ min;console.log(`🎲 Numero Aleatorio generado entre ${min} y ${max}: ${randomNumer}`);
const args = process.argv.slice(2);let min =1;let max =100;if(args.length>=2){const parsedMin =parseInt(args[0],10);const parsedMax =parseInt(args[1],10);if(!isNaN(parsedMin)&&!isNaN(parsedMax)&& parsedMin < parsedMax){ min = parsedMin; max = parsedMax;}else{console.log(`⚠️ Rango inválido. Usando valores por defecto (1-100).`);return;}}const randomNumber =Math.floor(Math.random()*(max - min +1))+ min;console.log(`🎲 Número aletatorio generado entre ${min} - ${max}: ${randomNumber}`);if( randomNumber %2==0){console.log("El numero generado es par");}else{console.log("El numero generado es impar");}
Gran explicación, lo estoy entendiendo al 100%.
Comparto mi solución, como aporte o valor agregado, le añadí colores a mis respuestas en la terminal, junto con process.exit(1) (para salir y finalizar el proceso con un código de error) y process.exit(0) para finalizar con exito.
Documentación ANSI Scape code:
// Array que contiene los argumentos de la línea de comandos!/*
* El primer elemento es la ruta del ejecutable de Node.js, el segundo es la ruta del ejecutable
* del script, y los siguientes son los argumentos proporcionados por el usuario.
*/// * Cuidado con los errores de sintaxis 'typo'const args = process.argv.slice(2);let min =1;let max =100;try{if(args.length==2){ min =parseInt(args[0],10);// --> Convierte el primer argumento en un entero, base 10 max =parseInt(args[1],10);if(isNaN(min)&&isNaN(max)|| min > max){thrownewError('⚠️ Invalid arguments. Please provide two numbers where the first is less than the second.');}const randomNumber =Math.floor((Math.random()*(max - min +1))+ min);// --> Genera un número aleatorio entre min y max, incluyendo a ambos extremos.console.log(`\x1b[32m🎲 Generating Random number between ${min} - ${max}: ${randomNumber}\x1b[0m`)}elseif(args.length==0){const randomNumber =Math.floor((Math.random()*(max - min +1))+ min);console.log(`\x1b[32m🎲 Generating Random number between ${min} - ${max}: ${randomNumber}\x1b[0m`)}}catch(error){console.error(error.message); process.exit(1);// --> Salir del proceso con un código de error.}finally{console.log('✅ Ejecución finalizada') process.exit(0);// --> Salir del proceso con un código de éxito.}// Para ejecutar el script en la terminal se usa el siguiente comando:// * node src/index.js 40 50
Hice una pequeña modificación en el código para independizar del órden de los argumentos que se le pasa al script :D
const args = process.argv.slice(2)let min =1let max =100if(args.length>=2){const parsedMin =parseInt(Math.min(...args))const parsedMax =parseInt(Math.max(...args))if(!isNaN(parsedMin)&&!isNaN(parsedMax)){ min = parsedMin
max = parsedMax
}else{console.log('⚠️ Rango inválido. Usando valores por defecto (1-100)')}}const randomNumber =Math.floor(Math.random()*(max - min +1)+ min)console.log(`🎲 Número aleatorio generado entre ${min} y ${max}: ${randomNumber}`)
const args = process.argv.slice(2);let min =1;let max =100;if(args.length>=2){ const parsedMin =parseInt(args\[0],10); const parsedMax =parseInt(args\[1],10); if(!isNaN(parsedMin)&&!isNaN(parsedMax)){ if(parsedMin \< parsedMax){  min = parsedMin;  max = parsedMax; }else{ console.log("‼️El primer argumento debe ser menor que el segundo. Se generara con valores (1-100)\n"); } }else{ console.log("❌Los argumentos deben ser numericos. Se generara con valores (1-100)\n"); }}const randomNumber =Math.floor(Math.random() \*(max - min +1))+ min;console.log(`🎲Número aleatorio generado entre ${min} y ${max}: ${randomNumber}`);
Mi resultado:
try{const[minArg, maxArg]= process.argv.slice(2).map(Number);console.log('Arguments:',[minArg, maxArg]);// Validar que ambos argumentos existan y sean números const min =Number(minArg);const max =Number(maxArg);const argsValidos =!isNaN(min)&&!isNaN(max)&& minArg !==undefined&& maxArg !==undefined&& min < max;if(!argsValidos){thrownewError('⚠ Argumentos inválidos. Usando valores por defecto (1-100).');}const randomNumber =Math.floor(Math.random()*(max - min +1))+ min;// Generar número aleatorio entre min y max (incluidos)console.log(`🎲 Número aleatorio entre ${min} y ${max}: ${randomNumber}`);}catch(error){console.error(`⚠ Error: ${error.message}`);console.log('ℹ Usa: node script.js <min> <max>');}