I'm trying to get JSDOC (3) to properly document my NodeJS modules. While simple modules work, I can't find the way to document a slightly more complex module.
My NodeJS module has the following structure:
/** @module MyModule */
(function() {
     function functionToExportOne {...}
     function functionToExportTwo {...}
     /** 
      * @module MyModule.ClassToExportOne
      * @constructor 
      */
     function ClassToExportOne {
           this.classMethodOne=function() { ... }
           this.classMethodTwo=function() { ... }
     }
     /** @constructor */
     function ClassToExportTwo {
           function classMethodOne() { ... }
           function classMethodTwo() { ... }
           return /** @lends {ClassToExportTwo.prototype} */ {
               methodOne:classMethodOne,
               methodTwo:classMethodTwo
           }
     }
     /** @exports MyModule */  <--- late addition, see comments
     module.exports={
         functionOne:functionToExportOne,
         functionTwo:functionToExportTwo,
         classOne:ClassToExportOne,
         classTwo:ClassToExportTwo
     }
})()
Well, as you see, the module exports both methods and class constructors. Nothing very strange.
The problem is, JSDOC
ClassToExportOne, when I use @module MyModule.<className> followed by @constructor (in this order) : In this case the class is recognized, but only the constructor is documented, and its methods are documented as belonging to the parent moduleI've tried thousands of different combinations without success:
this.method=function() {...} (as depicted in ClassToExportOne) or returning an object with methods using @lends {ClassToExportTwo.prototype} (as depicted in ClassToExportTwo)@module MyModule.ClassToExportOne in the header of each class@private, declaring everything @private but the exports@module declaration to just before the first exports (total mess then, some stuff gets promoted to "global" even though it's inside the main closure!!)@exports <modulename> just before the exports declaration, the methods are documented (mixed with the class methods)I've tried everything suggested in http://usejsdoc.org/howto-commonjs-modules.html without success.
I'm sure I'm missing something, but can't find what.
The following works for me with jsdoc 3.3.3:
/**
 * Example model.
 *
 * @module model/example
 */
module.exports = (function () {
    /**
     * Constructor function.
     *
     * @exports model/example.Example
     * @constructor
     * @param {string} id
     */
    var example = function Example(id) {
        this.id = id;
    };
    /**
     * Returns the ID.
     *
     * @memberof model/example.Example
     * @returns {string} the id
     */
    example.prototype.getId = function () {
        return this.id;
    };
    return example;
}());
and an example creating an instance of the model:
var example = new Example("ID");
console.log(example.getId());
                        I hate to answer my own question, but with a little more trial and error I got quite satisfactory results. Please feel free to comment if this is a correct approach, but the fact is the documentation is now properly generated :)
The key seems to be to use @exports <modulename>.<classname> before @constructor , this way the class appear in the index under "classes", and with its methods properly documented IF the methods are declared with this.method=function() {...} 
I still would like to find a way to make this work, if at all possible, for the case depicted in ClassToExportTwo , sometimes it's very convenient for me to define a class like this, specially for long classes that call private methods so I can avoid totally using "this" inside the class (optimization).
Well here's the template that works for me:
/** @module MyModule */
(function() {
     function functionToExportOne {...}
     function functionToExportTwo {...}
     /** works !!
      * @exports MyModule.ClassToExportOne
      * @constructor 
      */
     function ClassToExportOne {
           function innerMethod() { ... }
           // this works: assigning methods to this
           this.classMethodOne=function() { ... }
           this.classMethodTwo=function() { ... }
     }
     /** does not work
      * @exports MyModule.ClassToExportTwo
      * @constructor 
      */         
     function ClassToExportTwo {
           function classMethodOne() { ... }
           function classMethodTwo() { ... }
           // this DOES NOT WORK !! Methods get mixed with parent module
           return  {
               methodOne:classMethodOne,
               methodTwo:classMethodTwo
           }
     }
     // no more @exports here as it duplicates definitions in the docs
     module.exports={
         /** blah blah function description */
         functionOne:functionToExportOne,
         /** blah blah function description */
         functionTwo:functionToExportTwo,
         /** blah blah function description */
         classOne:ClassToExportOne,
         /** blah blah function description */
         classTwo:ClassToExportTwo
     }
})()
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With