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:
- El propósito general de la entidad (función, clase, etc.).
- Descripción de cada parámetro (
@param).- Descripción del valor de retorno (
@returns).- Descripción de las excepciones que puede lanzar (
@throws).- Ejemplos de uso (
@example) cuando sea relevante.- Marcar código obsoleto (
@deprecated) con una explicación o alternativa.- Usar
@seepara 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.
- 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.- 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).- 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.
- TypeScript Compiler (
tsc): Configurartsconfig.jsoncon opciones estrictas (strict: trueo equivalentes comostrictNullChecks,noImplicitAny, etc.) para aprovechar al máximo la seguridad de tipos.- 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.jsoncon scripts paralint,format,build.- Archivo
.eslintrc.jsonconfigurado. - Archivo
.prettierrc.jsonconfigurado. - Archivo
tsconfig.jsonconstrict: 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.jsonsin opcionesstrict, 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
tscsiguen 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.
- 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.- Manejo de Módulos: Asegurar compatibilidad (ESM preferido, CommonJS solo si es inevitable en Node.js legacy).
- Seguridad: Aplicar consideraciones de seguridad específicas (ej. no exponer claves secretas en frontend, validar todo en backend).
- Asincronía: Manejar la asincronía adecuadamente en ambos entornos (Event Loop en ambos, pero con APIs diferentes).
- Variables de Entorno: Acceder a variables de entorno de forma segura (
process.enven 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.