Saltar al contenido principal

Herramientas y Entorno

21. Reglas de Documentación de Código (JSDoc / TSDoc)

Regla Principal

Regla: Todo código público (funciones exportadas, clases, métodos públicos, interfaces, tipos exportados) debe incluir documentación utilizando comentarios TSDoc (una extensión de JSDoc para TypeScript). La documentación debe explicar:

  1. El propósito general de la entidad (función, clase, etc.).
  2. Descripción de cada parámetro (@param).
  3. Descripción del valor de retorno (@returns).
  4. Descripción de las excepciones que puede lanzar (@throws).
  5. Ejemplos de uso (@example) cuando sea relevante.
  6. Marcar código obsoleto (@deprecated) con una explicación o alternativa.
  7. Usar @see para referencias relacionadas.

Contexto y Justificación

La documentación clara y estandarizada es vital para la mantenibilidad, la colaboración y la comprensión del código, especialmente en equipos o proyectos grandes. TSDoc permite generar documentación automáticamente y proporciona información útil a través de herramientas de desarrollo (IDEs).

Ejemplos y Contraejemplos

  • Correcto (Documentación TSDoc Completa):
    /**
    * Calcula la suma de dos números.
    *
    * @param a El primer sumando.
    * @param b El segundo sumando.
    * @returns La suma de a y b.
    * @throws {TypeError} Si alguno de los argumentos no es un número.
    * @example
    * ```ts
    * const resultado = sumarNumeros(5, 3); // resultado es 8
    * ```
    * @see {@link restarNumeros} Para la operación inversa.
    */
    export function sumarNumeros(a: number, b: number): number {
    if (typeof a !== 'number' || typeof b !== 'number') {
    throw new TypeError('Ambos argumentos deben ser números.');
    }
    return a + b;
    }

    /**
    * Representa un usuario del sistema.
    * @deprecated Usar `UserProfile` en su lugar a partir de v2.0.
    */
    export interface UsuarioLegacy {
    id: number;
    nombre: string;
    }
  • Incorrecto (Sin documentación o incompleta):
    // INCORRECTO: Sin documentación
    export function procesar(data) {
    // ... lógica compleja ...
    }

    // INCORRECTO: Documentación mínima e inútil
    /**
    * Función que procesa
    * @param data // ¿Qué es data?
    * @returns algo // ¿Qué es algo?
    */
    export function procesarIncompleto(data: any): any {
    // ...
    }

Cuándo Aplicar

Obligatorio para todas las API públicas (exportadas) del código.

Cuándo Evitar o Flexibilizar

No es estrictamente necesario para código interno (no exportado) o muy trivial y autoexplicativo, aunque sigue siendo buena práctica. Priorizar la documentación de interfaces públicas y lógica compleja.

22. Reglas sobre Herramientas de Desarrollo (Linters, Formatters, Bundlers)

Regla Principal

Regla: Todo proyecto debe configurar y utilizar herramientas estándar para asegurar la calidad, consistencia y optimización del código.

  1. Linter (ESLint): Configurar ESLint con reglas apropiadas (ej. eslint:recommended, plugin:@typescript-eslint/recommended, plugins específicos de framework) para detectar errores de código, potenciales bugs y violaciones de estilo.
  2. Formatter (Prettier): Configurar Prettier para formatear automáticamente el código según un estilo consistente (integrado con ESLint si es posible: eslint-config-prettier).
  3. Bundler (Webpack, Vite, Rollup, esbuild): Utilizar un bundler moderno para aplicaciones frontend o librerías complejas, para empaquetar módulos, transpilar código (si es necesario), optimizar (minificación, tree-shaking) y gestionar assets.
  4. TypeScript Compiler (tsc): Configurar tsconfig.json con opciones estrictas (strict: true o equivalentes como strictNullChecks, noImplicitAny, etc.) para aprovechar al máximo la seguridad de tipos.
  5. Integración: Estas herramientas deben integrarse en el flujo de trabajo (IDE, Git hooks con Husky/lint-staged) para asegurar su aplicación.

Contexto y Justificación

Estas herramientas automatizan tareas esenciales de calidad y optimización, liberando a los desarrolladores (y a la IA) para enfocarse en la lógica. Aseguran consistencia en el código base, detectan errores temprano y preparan el código para producción.

Ejemplos y Contraejemplos

  • Correcto (Configuración Típica - Conceptual):
    • package.json con scripts para lint, format, build.
    • Archivo .eslintrc.json configurado.
    • Archivo .prettierrc.json configurado.
    • Archivo tsconfig.json con strict: true.
    • Archivo de configuración del bundler (vite.config.ts, webpack.config.js).
    • Husky/lint-staged configurado para lint/format pre-commit.
  • Incorrecto (Sin herramientas o mal configuradas):
    • Ausencia de ESLint/Prettier, resultando en código inconsistente y errores no detectados.
    • tsconfig.json sin opciones strict, perdiendo seguridad de tipos.
    • No usar bundler para una aplicación frontend grande, resultando en mala performance y manejo manual de dependencias.

Cuándo Aplicar

Obligatorio para todos los proyectos JS/TS, adaptando la configuración específica (plugins, reglas) al tipo de proyecto (Node.js, React, Vue, etc.).

Cuándo Evitar o Flexibilizar

Para scripts muy pequeños y aislados, la configuración completa puede ser excesiva, pero ESLint/Prettier y tsc siguen siendo altamente recomendados. La elección del bundler dependerá de los requisitos del proyecto.

23. Reglas sobre Consideraciones Específicas del Entorno (Node.js vs Navegador)

Regla Principal

Regla: La IA debe generar código apropiado para el entorno de ejecución especificado (Node.js o Navegador), utilizando las APIs y patrones correctos para cada uno.

  1. APIs del Entorno: Utilizar APIs específicas del navegador (DOM, fetch, window, localStorage) solo en código frontend. Utilizar APIs de Node.js (fs, path, http, process) solo en código backend.
  2. Manejo de Módulos: Asegurar compatibilidad (ESM preferido, CommonJS solo si es inevitable en Node.js legacy).
  3. Seguridad: Aplicar consideraciones de seguridad específicas (ej. no exponer claves secretas en frontend, validar todo en backend).
  4. Asincronía: Manejar la asincronía adecuadamente en ambos entornos (Event Loop en ambos, pero con APIs diferentes).
  5. Variables de Entorno: Acceder a variables de entorno de forma segura (process.env en Node.js, mecanismos específicos de build/framework en frontend, nunca directamente en código frontend).

Contexto y Justificación

Node.js y el Navegador son entornos muy diferentes con APIs y modelos de ejecución distintos. Escribir código que no considere estas diferencias llevará a errores en tiempo de ejecución, vulnerabilidades de seguridad o comportamiento incorrecto.

Ejemplos y Contraejemplos

  • Correcto (Código específico del entorno):
    // --- Código Frontend (Navegador) ---
    function actualizarTitulo(nuevoTitulo: string) {
    document.title = nuevoTitulo; // API del DOM
    localStorage.setItem('ultimoTitulo', nuevoTitulo); // API del Navegador
    }
    async function obtenerConfig() {
    const response = await fetch('/api/config'); // API del Navegador
    return response.json();
    }

    // --- Código Backend (Node.js) ---
    import fs from 'fs/promises';
    import path from 'path';
    import http from 'http';

    async function leerArchivoConfig() {
    const configPath = path.join(__dirname, 'config.json');
    const data = await fs.readFile(configPath, 'utf-8'); // API Node.js
    return JSON.parse(data);
    }
    const PORT = process.env.PORT || 3000; // API Node.js
    http.createServer((req, res) => { /* ... */ }).listen(PORT);
  • Incorrecto (Mezcla de APIs):
    // INCORRECTO: Intentar usar API de Node.js en Navegador
    // function guardarLogFrontend(mensaje: string) {
    // const fs = require('fs'); // Error: require is not defined
    // fs.writeFileSync('log.txt', mensaje);
    // }

    // INCORRECTO: Intentar usar API del DOM en Node.js
    // function obtenerInfoDesdeDOM_Backend() {
    // return document.getElementById('data')?.textContent; // Error: document is not defined
    // }

Cuándo Aplicar

Siempre. El código debe ser consciente de su entorno de ejecución.

Cuándo Evitar o Flexibilizar

En código isomórfico/universal (diseñado para ejecutarse en ambos entornos), se deben usar abstracciones o conditional checks para manejar las diferencias de API. Sin embargo, la norma general es usar las APIs correctas para el entorno objetivo.