Generación de documentación técnica
De Comentarios a Documentación Viva: Herramientas que Trabajan por Ti
Escribir código limpio es solo la mitad de la batalla. La otra mitad es asegurarte de que cualquiera pueda entenderlo y usarlo correctamente, sin tener que descifrar cada línea. Las herramientas modernas de documentación técnica transforman tus comentarios y la estructura de tu código en manuales interactivos y siempre actualizados. No se trata de escribir más, sino de escribir de forma más inteligente, permitiendo que las máquinas generen la documentación profesional por ti.
Es como la diferencia entre un chef que guarda sus recetas en notas sueltas y otro que usa un libro de recetas bien indexado con fotos.
JSDoc y TypeDoc son el sistema de archivo que organiza tus "recetas" (funciones). Swagger/OpenAPI es el menú completo del restaurante, mostrando cada plato (endpoint) y sus ingredientes.
Documentación de Código Fuente: De Comentarios a Contratos Ejecutables
El problema más común no es la falta de comentarios, sino comentarios inútiles que repiten lo obvio. Las convenciones como JSDoc (para JavaScript) convierten tus comentarios en contratos técnicos. Al documentar una función, describes explícitamente qué espera recibir (parámetros, sus tipos), qué promete devolver y qué hace. Herramientas como el generador de jsdoc pueden tomar todos estos comentarios estructurados y crear un sitio web HTML completo con una navegación elegante por todas tus funciones, clases y módulos.
La magia está en que esta documentación se genera a partir del código mismo. Si cambias los parámetros de una función pero olvidas actualizar el comentario JSDoc, la documentación generada estará desactualizada, lo que sirve como una señal de alerta. Esto es especialmente poderoso en TypeScript con TypeDoc, donde los tipos ya están definidos, y la herramienta puede extraer automáticamente gran parte de la documentación, dejándote centrar en explicar el "por qué" y la lógica de negocio.
Regla mental básica
Un comentario JSDoc responde siempre a tres cosas:
- Qué hace esta función
- Qué recibe
- Qué devuelve
- Qué errores puede lanzar (si aplica)
Nada más.
Sintaxis mínima que debes memorizar
Un bloque JSDoc siempre empieza así:
/**
* Texto descriptivo.
*/
Y dentro se usan etiquetas:
@parampara parámetros@returnspara retorno@throwspara errores@typedefpara tipos@templatepara genéricos
Ejemplo 1. Función simple
Código:
function sumar(a, b) {
return a + b;
}
Mismo código con JSDoc útil:
/**
* Suma dos números.
*
* @param {number} a Primer número.
* @param {number} b Segundo número.
* @returns {number} Resultado de la suma.
*/
function sumar(a, b) {
return a + b;
}
Qué gana el editor:
- Autocompletado
- Avisos si pasas algo que no es number
- Tooltip al pasar el ratón
Ejemplo 2. Función que puede fallar
Código:
function dividir(a, b) {
if (b === 0) {
throw new Error("No se puede dividir por cero");
}
return a / b;
}
Con JSDoc:
/**
* Divide dos números.
*
* @param {number} a Dividendo.
* @param {number} b Divisor.
* @returns {number} Resultado de la división.
* @throws {Error} Si b es 0.
*/
function dividir(a, b) {
if (b === 0) {
throw new Error("No se puede dividir por cero");
}
return a / b;
}
Ahora el contrato dice: esta función puede lanzar error. No es sorpresa.
Ejemplo 3. Función asíncrona
Código:
async function cargarUsuario(id) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
Con JSDoc:
/**
* Carga un usuario desde la API.
*
* @param {string} id Identificador del usuario.
* @returns {Promise<Object>} Usuario en formato JSON.
* @throws {Error} Si la petición falla.
*/
async function cargarUsuario(id) {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) {
throw new Error("Fallo al cargar usuario");
}
return res.json();
}
Clave:
Las funciones async siempre devuelven Promise<tipo>.
Ejemplo 4. Definir un tipo con @typedef
Si trabajas con objetos, no repitas la estructura en cada función.
Define el tipo una vez:
/**
* Usuario del sistema.
* @typedef {Object} User
* @property {string} id Identificador único.
* @property {string} name Nombre del usuario.
* @property {string} email Correo electrónico.
*/
Y úsalo así:
/**
* Crea un usuario.
*
* @param {string} name Nombre.
* @param {string} email Email.
* @returns {User} Usuario creado.
*/
function crearUsuario(name, email) {
return {
id: crypto.randomUUID(),
name,
email
};
}
El editor ya sabe qué campos tiene User.
Ejemplo 5. Función genérica con @template
Para utilidades reutilizables:
/**
* Devuelve el primer elemento de un array.
*
* @template T
* @param {T[]} arr Array de cualquier tipo.
* @returns {T | undefined} Primer elemento o undefined.
*/
function first(arr) {
return arr[0];
}
Ahora first([1,2,3]) es number.
first(["a","b"]) es string.
Regla práctica para usar JSDoc sin perder tiempo
- Documenta solo funciones públicas o importantes
- Usa
@paramy@returnssiempre - Usa
@throwssolo cuando realmente lanzas errores - Define
@typedefpara tus modelos (User, Note, Product) - No expliques obviedades. Documenta contratos y límites
Patrón mínimo recomendado
Para cualquier función real:
/**
* Qué hace.
*
* @param {tipo} nombre Qué es.
* @returns {tipo} Qué devuelve.
* @throws {Error} Cuándo falla.
*/
Resultado real
- El editor entiende tu código
- Autocompletado fiable
- Menos errores por mal uso
- Contratos claros entre funciones
- Sin TypeScript
- Sin runtime overhead
Eso es JSDoc en su forma útil y mínima.
Swagger/OpenAPI y TypeDoc: Documentación que se Prueba y Navega
Cuando tu proyecto crece e incluye un backend con una API, necesitas una forma estandarizada de describir cada "puerta de entrada" (endpoint). Aquí es donde Swagger/OpenAPI se vuelve indispensable. En lugar de escribir un documento de texto que describe tu API (y que inevitablemente se desfasa), defines un archivo openapi.yaml o openapi.json. Este archivo es la fuente de verdad de tu API: declara rutas, métodos, los datos exactos que espera recibir (en JSON) y lo que devolverá.
La ventaja abrumadora es que herramientas como Swagger UI o Redoc pueden tomar este archivo y generar automáticamente una interfaz web interactiva. Los desarrolladores pueden navegar por los endpoints, ver ejemplos y, lo más importante, probar las llamadas a la API directamente desde el navegador. Esto elimina horas de configuración en Postman y asegura que la documentación y la API real están siempre sincronizadas.
Ejemplo Práctico: Especificación OpenAPI para un Endpoint (Backend)
Este fragmento YAML define claramente cómo interactuar con un endpoint.
paths:
/api/usuarios:
post:
summary: Crea un nuevo usuario.
description: Registra un nuevo usuario en el sistema. El email debe ser único.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, password]
properties:
email:
type: string
format: email
example: "usuario@ejemplo.com"
password:
type: string
format: password
minLength: 8
example: "miClaveSecreta123"
responses:
'201':
description: Usuario creado exitosamente.
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 42
email:
type: string
example: "usuario@ejemplo.com"
Automatización en CI/CD: La Documentación que Nunca Envejece
El mayor enemigo de la documentación es la obsolescencia. Puedes tener las mejores herramientas, pero si la documentación generada no se actualiza automáticamente con cada cambio en el código, pronto se volverá inútil. Aquí entra la automatización con CI/CD (Integración Continua/Despliegue Continuo).
La idea es simple: configuras un flujo de trabajo (por ejemplo, en GitHub Actions o GitLab CI) que, cada vez que se hace un cambio en la rama principal del código (como main):
- Genera la documentación automáticamente (ejecuta
jsdocotypedoc). Imagina que GitHub Actions es un "robot invisible" que vive en tu repositorio. Este robot se queda vigilando y, cada vez que tú subes cambios (haces unpush), él se pone a trabajar automáticamente. - Construye el sitio web de la documentación (por ejemplo, con MkDocs o el propio HTML generado).
- Despliega ese sitio en un lugar público (como GitHub Pages o Netlify).
El resultado es que tu documentación pública está siempre viva y sincronizada con la última versión estable de tu código. Si el proceso de generación falla porque un comentario JSDoc está mal formado, el flujo de trabajo también fallará, impidiendo que se despliegue código roto. Esto convierte a la documentación en un ciudadano de primera clase en tu proceso de desarrollo, no en un apéndice olvidado.
¿Cómo funciona el proceso? (Paso a paso)
- Tú programas: Escribes tu código con los comentarios JSDoc (como vimos antes) y lo subes a GitHub.
- El Robot se activa: GitHub detecta que hay código nuevo y "despierta" a la Action que hayas configurado.
- El Robot lee y crea: El robot ejecuta un comando que lee tus archivos
.js, extrae el JSDoc y genera una carpeta con archivos HTML (la documentación visual). - El Robot publica: El mismo robot toma esos archivos HTML y los sube a un servidor (normalmente GitHub Pages) para que cualquiera pueda ver la documentación en una URL tipo
tu-usuario.github.io/tu-proyecto.
¿Por qué es tan útil?
Sin GitHub Actions, tendrías que:
- Generar la documentación en tu PC manualmente.
- Subirla a mano a algún sitio.
- Repetir esto cada vez que cambies una línea de código.
Con GitHub Actions, te olvidas. Tú solo te preocupas de escribir el código; la documentación se mantiene actualizada sola, como por arte de magia.
¿Qué aspecto tiene una "instrucción" para este robot?
Para que esto funcione, creas un archivo pequeño (llamado YAML) en una carpeta especial de tu proyecto. Se ve algo así de simple:
name: Generar Documentación
on: [push] # El robot se activa al hacer push
jobs:
construir-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # El robot baja tu código
- name: Crear HTML de JSDoc
run: npx jsdoc src/*.js # El robot genera la web de docs
- name: Publicar
uses: JamesIves/github-pages-deploy-action@v4 # El robot la sube a internet
with:
folder: out # La carpeta donde se guardó la documentación
Resumen sencillo
- JSDoc: Es el contenido (lo que escribes).
- GitHub Actions: Es el trabajador (el que procesa ese contenido).3
- GitHub Pages: Es el escaparate (donde se muestra la web resultante).4
Ejemplo Práctico: Flujo de GitHub Actions para Documentación
Un fragmento de un archivo .github/workflows/docs.yml que automatiza todo.
name: Desplegar Documentación
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout código
uses: actions/checkout@v3
- name: Configurar Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Instalar dependencias y generar docs
run: |
npm ci
npm run docs:generate # Este script ejecuta 'typedoc --out ./docs'
- name: Desplegar a GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs # Publica la carpeta generada
Conclusión: Llevándolo a la Práctica
Adoptar estas herramientas no es una complejidad añadida, es una simplificación a largo plazo. Te liberan de la tediosa tarea de mantener documentos manuales y, lo más importante, construyen confianza. Los desarrolladores que usan tu API confían en la documentación interactiva, los nuevos miembros del equipo comprenden el código base más rápido con los sitios generados, y tú nunca más tendrás que responder "la documentación está desactualizada".
Consejos para Aplicar el Conocimiento
- Empieza con JSDoc hoy: En tu próximo archivo JavaScript, elige una función y escribe su comentario JSDoc. Luego, instala
jsdocglobalmente (npm i -g jsdoc) y genera tu primer sitio web de documentación local. Ver la diferencia es motivador. - Juega con Swagger UI para tu API: Si tienes un backend en Node.js/Express, busca la librería
swagger-jsdocoswagger-ui-express. En 30 minutos puedes tener una ruta/api-docsen tu propio servidor que muestre la documentación interactiva de tus endpoints. - Automatiza un despliegue simple: Crea un repositorio de ejemplo en GitHub, añade un
README.mdy configura GitHub Pages en los ajustes del repositorio. Ver cómo un cambio en tuREADMEse refleja al instante en una web pública te dará la confianza para luego automatizar herramientas más complejas. Dominar este flujo te posiciona como un desarrollador moderno y metódico, capaz de crear productos que son tan fáciles de usar como de mantener.