5

UPDATE: @spenibus helped me reach the conclusion that this may be an issue with JSDoc itself. I added my findings to this open issue on their GitHub. @spenibus found a solution, but it requires a slightly altered version of the IIFE

I'm using an IIFE in a CommonJS module to be able to work with CommonJS and fallback to assigning the interface to the window object if it module.exports doesn't exist. How do I properly document this so that the passed in exports object is treated as module.exports?

/**
 * This is a description
 * @module someModule
 */
(function (exports) {

    /**
     * Returns true if something.
     * @param {String} type
     * @returns {boolean}
     * @static
     */
    var isSomething = function isSomething(type){
        return true;
    };

    exports.isSomething = isSomething;

})(
    //if exports exists, this is a node.js environment so attach public interface to the `exports` object
    //otherwise, fallback to attaching public interface to the `window` object
    (typeof exports === 'undefined') ?
         window
        : exports
);
ejfrancis
  • 2,925
  • 4
  • 26
  • 42
  • What doesn't work ? Any error ? Because there are a few syntax issues in this code but the logic seems fine. – spenibus Aug 07 '15 at 01:20
  • @spenibus no error but it doesn't recognize the "exports" object passed in through a ternary operator to the IIFE as being the public interface. the generated docs only have the "someModule This is a description" at the top of the HTML page but nothing else, the public "isSomething" method doesn't get mentioned in the HTML, nor any other public interface methods/objects attached to "exports" – ejfrancis Aug 10 '15 at 17:33

1 Answers1

3

While JSDoc issue 456 seems relevant that's not getting us anywhere yet.

I had a look at Use JSDoc: @alias which, while promising, did not offer the same JSDoc output.

Then I tried something simple, which had me playing the FF7 victory theme in my head, AKA it worked:

/**
 * This is a description
 * @module someModule
 */

(function() {

    // export to window when not used as a module
    if(typeof exports === 'undefined') {
        var exports = window;
    }

    /**
     * Returns true if something.
     * @param {String} type
     * @returns {boolean}
     * @static
     */
    exports.isSomething = function(type){
        return true;
    };
})();

Using jsdoc ./ on the project dir resulted in the same output as if I had not used an IIFE. The basic idea is to always have an object named exports and simply modify what it references.

Nodejs test

var mm = require('./module.js');

console.log('--Testing nodejs--');
console.log(mm);

Output:

--Testing nodejs--
{ isSomething: [Function] }

Html script test

<script src="module.js"></script>
<script>
    console.log('--html script test--');
    console.log(isSomething.toString());
</script>

Output:

"--html script test--"
"function (type){
    return true;
}"

Update 2015-08-13 05:10 +0000
Moved window exportation inside the IIFE to avoid extra exports var laying around in html script.

spenibus
  • 4,339
  • 11
  • 26
  • 35
  • ignore the syntax error, that was a mistake when I was copying over the code and removing any project-specific stuff (company doesn't like sharing their code). I've boiled it down to just the following (plus the @module declaration), it's still not generating anything other than the module name/description. FWIW, I'm using JSDoc 3.3.0-alpha5 and a DocStrap theme via the "gulp-jsdoc" gulp task (function (exports) { exports.isSomething = function(type){ return true; }; }( typeof exports === 'undefined'? window: exports)); – ejfrancis Aug 10 '15 at 21:13
  • The code you just provided still has the same syntax issue of mismatched parentheses. – spenibus Aug 10 '15 at 21:17
  • whoops yeah you're right. well I changed it so the file only contains the @module tag and this code, still doesn't work. (function (exports) { exports.isSomething = function(type){ return true; }; })( typeof exports === 'undefined'? window: exports); – ejfrancis Aug 10 '15 at 21:21
  • How do you call `isSomething` ? – spenibus Aug 10 '15 at 21:25
  • it's a static method, so something like var someModule = require('someModule'); someModule.isSomething('foo') – ejfrancis Aug 10 '15 at 21:30
  • It only fails the exports part ? window is fine ? Did you define exports beforehand as `var exports = module.exports` ? Or just use `typeof module.exports === 'undefined' ? window : module.exports`. – spenibus Aug 10 '15 at 21:36
  • not declaring it ahead of time. here's the exact file I'm using for testing purposes. http://pastebin.com/xMBaVrzs – ejfrancis Aug 10 '15 at 21:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86647/discussion-between-spenibus-and-ejfrancis). – spenibus Aug 10 '15 at 21:40