Saltar al contenido

Cómo construir un CLI útil en Node.js o Python

7 min de lectura Software
  • cli
  • node.js
  • python
  • herramientas
  • scripts

Un CLI (Command Line Interface) bien construido puede transformar tareas repetitivas en procesos que se ejecutan con una sola línea de código. No hablo de un script de usar y tirar, sino de una herramienta que tu equipo —o tú mismo— usará a diario para resolver problemas específicos. La diferencia entre un script y un CLI útil radica en la interfaz, la robustez y cómo maneja los errores.

Mi regla es simple: si vas a ejecutar algo más de tres veces, merece la pena convertirlo en un CLI.

Diseño de un CLI útil

Construir un CLI no es solo escribir lógica, sino diseñar una experiencia. Un usuario debería poder ejecutar tu herramienta sin leer la documentación completa, solo pidiendo mi-cli --help. Esto significa que las opciones deben ser claras, los comandos intuitivos y los mensajes de error, descriptivos.

Un CLI bien diseñado ahorra tiempo doblemente: en la ejecución de la tarea y en la interpretación de los resultados. La diferencia entre un script.py -f data.csv -o output.json y un procesar-datos --file data.csv --output output.json puede parecer mínima, pero la legibilidad y la capacidad de descubrimiento son enormes. Esto reduce la fricción en el día a día de cualquier desarrollador.

Node.js para CLIs: Ventajas y herramientas

Node.js es una excelente opción para construir CLIs, especialmente si tu stack ya incluye JavaScript. Tienes acceso a un ecosistema de paquetes maduro para parsing de argumentos, interacción con el sistema de archivos y llamadas HTTP. Utilizo Node.js para CLIs que necesitan ser ejecutados en entornos donde ya hay npm o yarn disponible.

Herramientas como commander.js o yargs simplifican enormemente el trabajo. Permiten definir comandos, opciones y ayudas de forma declarativa, sin reinventar la rueda del parsing de argumentos.

#!/usr/bin/env node
const { Command } = require('commander');
const program = new Command();

program
  .name('mi-cli')
  .description('Herramienta CLI para gestionar proyectos')
  .version('1.0.0');

program.command('deploy')
  .description('Despliega la aplicación')
  .option('-e, --env <env>', 'Entorno de despliegue (dev, staging, prod)', 'dev')
  .action((options) => {
    console.log(`Desplegando en el entorno: ${options.env}`);
    // Lógica de despliegue aquí
  });

program.parse(process.argv);

Este bloque de código muestra cómo definir un comando deploy con una opción --env. Es conciso y fácil de entender.

Python para CLIs: Ventajas y herramientas

Python es otra alternativa robusta para el desarrollo de CLIs, apreciado por su sintaxis clara y su potente librería estándar. Es mi elección cuando la lógica de negocio requiere procesado de datos complejo o interacción con sistemas externos que ya tienen buenas librerías en Python. El ecosistema de Python es inmejorable para tareas de automatización.

Librerías como argparse (parte de la librería estándar) o Click hacen que la creación de CLIs sea intuitiva. Click en particular ofrece un enfoque muy elegante basado en decoradores, reduciendo el boilerplate.

import click

@click.group()
def cli():
    """Una herramienta CLI de ejemplo."""
    pass

@cli.command()
@click.option('--count', default=1, help='Número de saludos.')
@click.argument('name')
def hola(count, name):
    """Saluda a NAME un número COUNT de veces."""
    for x in range(count):
        click.echo(f"Hola {name}!")

if __name__ == '__main__':
    cli()

Aquí, Click permite definir un comando hola con una opción count y un argumento name de forma muy legible.

Comparativa: Node.js vs Python para CLIs

La elección entre Node.js y Python para tu CLI depende de varios factores, no solo de preferencia personal. Hay que considerar el entorno donde se ejecutará y las dependencias que arrastra.

CaracterísticaNode.js (JavaScript)Python
Curva de aprendizajeBaja si ya conoces JSBaja si ya conoces Python
RendimientoMuy bueno para I/O intensivoBueno para CPU intensivo (con extensiones C)
EcosistemaAmplio, orientado a web/servidorEnorme, orientado a datos/ML/automatización
DistribuciónRequiere node/npmRequiere python/pip
Tamaño finalMayor (node_modules)Menor (dependencias más ligeras)
IntegraciónIdeal si el stack es JSIdeal si el stack es Python, o para scripts de sistema

Si el CLI va a interactuar con APIs web o servicios basados en JavaScript, Node.js es una elección natural. Si la tarea es más de procesamiento de datos, automatización de sistemas o integración con modelos de IA, Python suele ser más eficiente. Siempre valoro la coherencia con el stack existente del proyecto para reducir la complejidad.

Estructura de proyecto para CLIs robustos

Un CLI robusto no es solo el main de tu script. Necesita una estructura de proyecto que facilite el mantenimiento y la evolución. Mi enfoque es separar la lógica de negocio de la interfaz de línea de comandos. Esto permite testear la lógica independientemente y cambiar la interfaz si es necesario.

Una buena estructura de proyecto de software previene la deuda técnica a largo plazo. Además, implementar testing automatizado asegura que los comandos funcionan como se espera, especialmente si manejan datos críticos. Un CLI sin tests es un riesgo en producción.

Cuando un cliente me llega con un script que ha crecido sin control, el primer paso es refactorizarlo para darle una estructura clara. Esto implica dividir las responsabilidades, usar funciones puras y manejar los errores de forma explícita.

Para profundizar en la gestión de proyectos de desarrollo, tengo un artículo sobre GitHub Actions para automatización de tareas que complementa bien el uso de CLIs. También, si tus CLIs interactúan con servicios externos, entender el diseño correcto de una API REST asegura integraciones robustas.

Lucas Juárez
Lucas Juárez

Técnico freelance especializado en desarrollo a medida, automatizaciones con IA y gestión técnica para negocios en España. Más sobre mí →

Compartir:

¿Necesitas desarrollo a medida?

Desarrollo funcionalidades específicas, integraciones entre sistemas y herramientas internas. Si se puede programar, probablemente puedo hacerlo.

Chat