简体   繁体   中英

Documenting factories with JSDoc

In order to avoid using new in my JavaScript code, I write factories to create objects.

I have tried many combinations and the one that gives me the most satisfactory result is the following:

/**
 * Document module
 * @module app/document
 */
(function () {
    'use strict';

    /**
     * Factory that creates a document object.
     * @alias module:app/document.factory
     * @return {document}
     */
    function document() {
        /**
         * Get document id
         * @method id
         * @return {String}
         */
        var id = function id() {...},
            api = {
                id: id
            };

        return api;
    }

    /**
     * This module exports the {@link module:app/document.factory|factory} function.
     */
    module.exports = document;
}());

The problem with these comments is there is no document object defined. Therefore, I can't reference this object in another object and I can't inherit its documentation when I extends this object.

What is the appropriate way to document this kind of object?

If I use the @typedef tag, I get the static factory method and the document object properly documented but no id method documentation is generated by JSDoc:

/**
 * Document module.
 * @module app/document
 */
(function () {
    'use strict';

    /**
     * Factory that creates a document object.
     * @function module:app/document.factory
     * @return {document}
     */
    function factory(agent) {
        /**
         * @callback document~id
         * @returns {String}
         */
        var id = function id() {...},

            /**
             * @typedef document
             * @property {document~id} id
             */
            document = {
                id: id
            };

        return document;
    }

    module.exports = factory;
}());

My recommendation to you is to well define the exports on your module using @typedef to define the type and then annotate the module.exports = factory with @type {FactoryDefinition}

 /** @typedef {{ id: !string }} */
 var DocumentDefinition;

 /** @typedef {!function(!object):!DocumentDefinition} */
 var FactoryDefinition;

/** @type {FactoryDefinition} */
module.exports = factory

I always use a @typedef outside my module wrapper where I summarise the complete set of functions exposed by the module. This is the only way I managed to get code completion in my WebStorm IDE and generate useful HTML documentation.

/** @namespace SharedLib */

/**
 * @typedef SharedLib.PriorityQueueFactory
 * @function
 * @template T
 * @param {function(T, T): Boolean} comparator Comparison function like for <code>Array.prototype.sort</code>
 * @return {{pop: function(Array<T>): Array<Array<T>| T>, push: function(Array<T>, T): Array<T>}} an object containing the functions to manage the queue
 */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    }
    else if (typeof module === 'object' && module.exports) {
        module.exports = factory();
    }
    else {
        root.returnExports = factory();
    }
}(typeof self !== 'undefined' ? self : this,
    function () {

        /** @type {SharedLib.PriorityQueueFactory} */
        function priorityQueueFactory(comparator) {
            const
                push = function(queue, item) {
                    const
                        clonedQueue = queue.slice();
                    clonedQueue.push(item);

                    return clonedQueue.sort(comparator);
                },
                // ...
            return {
                push: push,
                pop: pop
            };
        }

        return priorityQueueFactory;
}));

The generated docs look like this .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM