jsdocs y dan brown

Introducción al documentador de código jsdocs

Natalie Shau

archivado en: JavaScript / 4 enero, 2016

En If Hemingway wrote javaScript (No Starch Press, 2015), Angus Croll explica en clave de humor cómo picarían javaScript algunos escritores célebres, como Virginia Wolf, Borges, James Joyce o Arthur Conan Doyle. El libro está ilustrado Miran Lipovača y está maquetado con gran gusto. Sin duda, una lectura recomendable para quien gusta reflexionar sobre el código.

Según Croll, si Dan Brown, autor de best sellers de intriga como El código Da Vinci, escribiese javaScript, su estilo se caracterizaría entre otras cosas por el tono deductivo y la abundancia de comentarios explicativos.

/*

FACT: Some time in 1557, Michelangelo Moribundi, the renowned, bald-headed
alchemist, fashioned a secret code out of bits of asparagus and placed it in a
long-forgotten vault ...

*/

function theDaFibonacciCode(numeratiFettucini) {

// Wide awake, the bleary-eyed Langdon watched as two tall, lissome number

// ones, with big feet and a type of hat, sidled up to the rounded zero ...

var ilInumerati = [0,1,1];

// while theIntegerThatIncrementsOneByOne morphed eerily into a ... three.

theIntegerThatIncrementsOneByOne = 3,

// Now the silent ratio that could not be uttered had come to make it right.

TheBotticelliVector = 1.61803;

while (theIntegerThatIncrementsOneByOne < numeratiFettucini) {

// Somehow another number one appeared and theIntegerThatIncrementsOneByOne

// snatched at it gracefully.

theIntegerThatIncrementsOneByOne = theIntegerThatIncrementsOneByOne + 1;

// The renowned, rounded 16-bit unsigned integer tentatively succumbed to

// the strange force of the vector before pushing itself bodily into the

// hands of the weakly typed array.

ilInumerati.push(

Math.round(ilInumerati[theIntegerThatIncrementsOneByOne - 2] *

TheBotticelliVector)

);

}

// "Too many elementi?" reminded the five-foot-eleven, bushy-eyebrowed Italian.

// Too many elements?

if (ilInumerati.length > numeratiFettucini) {

// Intelligently, Langdon, sporting a Harris Tweed jacket (J.Crew, $79.99),

// sliced it with his Modell 1961 Ausführung 1994 Swiss Army knife.

ilInumerati = ilInumerati.slice(0, numeratiFettucini);

}

// The kaleidoscope of truth had been shaken. Now, in front of them, sat the

// numerically sequenced sequenza numerica. Like a gleaming cathedral.

 return ilInumerati;

 }

Esta manera de escribir código con tantos comentarios me parece fundamental. Dicen que el código bien formado no necesita comentarios, sin embargo, ni siquiera en este caso es lo bastante explícito por sí mismo. Cada cual tiene su estilo y la propia dinámica de los proyectos -cambios de opinión, ñapas para llegar a una entrega, una zona programada por alguien que está aprendiendo...- tiende a dejar partes oscuras.

Pero podemos hacer algo mejor que documentar el código y es hacerlo con jsdocs, una herramienta indispensable en cualquier proyecto a la que tenga un par de pantallas.

jsdocs

jsdocs, que en el momento de escribir estas líneas va por su tercera versión, consiste en dos cosas. Por un lado, una propuesta metodológica para documentar el código y, por otro, una especie de compilador que convierte todos los comentarios en una web navegable.

La documentación se realiza mediante «block tags», una serie de términos que se caracterizan por ir precedidos por una arroba (@).

/** @function

* @name bazinga

* @param {number} foo Un número formidable.

* @returns {boolean} Si foo es 1, devuelve true.

* @description Esta función comprueba si foo es 1 o no

*/

function bazinga(foo) {

if ( foo === 1 ) {

return true;

}

return false;

}

Hay una montonera de tags, pero más o menos con los expuestos en el ejemplo anterior va más que de sobra. Estos son:

  • @name: el nombre del método o el objeto.
  • @params: los parámetros que recibe.
  • @returns: los que devuelve.
  • @description: una breve descripción.

Además, cuando se trabaja con objetos, son muy útiles @namespace y @memberof para documentar los métodos y propiedades de cada uno, pues de lo contrario luego no se reflejan bien en la documentación generada de forma automática.

/**

* @namespace - miObjeto.

* @description - Este es un objeto formidable.

*/

var miObjeto = {

/** @memberof miObjeto.

* @name - miMetodo.

* @param {string} foo - Lore Ipsum.

* @param {string} [bar] - Este parámetro es opcional.

* @description - Este método consologuea foo.

* @example

* // Da por consola "Hola Mundo"

* miObjeto.miObjeto("Hola Mundo");

*/

miMetodo: function (foo) {

console.log(foo);

},

/** @memberof miObjeto.

* @name - otroMetodo.

* @deprecated since version 1.0

*/

otroMetodo: function() {

console.log("Soy un método que ya no se usa");

}

};

Esto por ejemplo, quedaría así una vez compilado el jsdoc.

jsdoc

Esta fórmula del @namespace para agrupar un conjunto de métodos y propiedades -ya sean de un objeto o una clase- es lo más práctico, aunque también existen otras fórmulas como la de @class.

/** @class

* @name MiClase.

* @param {string} unDatoInicial - Lore Ipsum.

* @param {string} otroDatoInicial - Lore Ipsum.

* @classdesc - Ejemplo documentación de clase.

*/

function MiClase (unDatoInicial, otroDatoInicial) {

this.unDatoInical = unDatoInicial;

this.otroDatoInicial = otroDatoInicial;

/**

* @memberof MiClase.

* @name metodoClase. */

this.metodoClase = function (bar) {

console.log(bar+this.unDatoInical);

};

};

Cualquier método relevante debe estar documentado.

Además, hay otro tipo de fórmulas muy interesantes, como la que nos proporciona el block tag @property, estupenda para documentar arrays y jsons.

/**

* @namespace

* @property {array} libros - Listado de libros.

* @property {number} libros.id - Id del libro.

* @property {string} libros.autor - Autor.

* @property {string} libros.titulo - Título.

*/

var todoLibros = {

libros: [

{

id: 1,

autor: 'Robert Louis Stevenson',

titulo: 'El doctor Jekyll y el señor Hyde'

}

]

};

Una fórmula que queda así de clara luego...

jsdoc-02

Bueno, quedarían algunas cosas más avanzadas por explicar, como los «tag inline», una especie de enlaces internos, los tutoriales, las plantillas o los plugins, pero las dejo para una segunda entrada y cierro esta explicando cómo se instala.

Instalación

Se puede utilizar directamente instalándolo con el npm, pero lo normal es que esté integrado en algún automatizador de tareas, como grunt. Yo suelo usar el plugin de krampstudio, que se instala en un periquete con el npm.

npm install grunt-jsdoc --save-dev

La configuración del Gruntfile.js es igual de sencilla.

module.exports = function(grunt) {

grunt.initConfig({

jsdoc : {

dist : {

src: ['*.js'],

options: {

destination: 'doc'

}

}

}

});

grunt.loadNpmTasks('grunt-jsdoc');

grunt.registerTask('default', ['jsdoc']);

};

Hay otro plugin digi-evolucionado para el grunt, el grunt-jsdoc-ng, pero en el momento de escribir estas líneas tiene un buguete que lo hace incompatible con la última versión de grunt.

He subido los ejemplos de esta entrada, incluido el doc generado, en git.

Update :: gulp

Hay un plugin para gulp que funciona mejor (y es más rápido) que el de grunt: gulp-jsdoc3 de mlucool. Va de perlas : )

|| Tags: ,

valoración de los lectores sobre jsdocs y dan brown

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 4.7 sobre 5 (3 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

2 respuestas a “jsdocs y dan brown

  1. Sencillo, directo y eficaz, como siempre.

    Gracias por el artículo. Lo mostraré para explicarle a unos compañeros ciertas funcionalidades del jsdoc.

    Solo echaría de menos un enlace en github o similares para descargar con un ejemplo sencillo.

    Para el jsdoc avanzado, podría ser interesante comentar su uso con la ayuda de IDE’s como Sublime TEXT y sus plugins o su uso frameworks/librerías importantes como en Polymer.

    Un saludo