web-dev-qa-db-fra.com

Comment puis-je utiliser les méthodes JSDoc d'un objet imbriqué?

J'ai essayé d'utiliser JSDoc3 pour générer de la documentation sur un fichier, mais j'ai quelques difficultés. Le fichier (qui est un module Require.js) ressemble en gros à ceci:

define([], function() {

    /*
     * @exports mystuff/foo
     */
    var foo = {
        /**
         * @member
         */
        bar: {
            /**
             * @method
             */
            baz: function() { /*...*/ }
        }
    };

    return foo;
}

Le problème est que je ne parviens pas à faire apparaître baz dans la documentation générée. Au lieu de cela, je viens d'obtenir un fichier de documentation pour un module foo/foo, qui répertorie un membre bar, mais bar n'a pas baz (juste un lien vers le code source de foo).

J'ai essayé de changer la directive de bar en @property à la place, et j'ai essayé de changer la directive de baz en @member ou @property, mais rien de tout cela n'aide. Peu importe ce que je fais, baz ne semble tout simplement pas vouloir se montrer.

Est-ce que quelqu'un sait quelle structure de directive je pourrais utiliser pour que baz apparaisse dans la documentation générée?

P.S. J'ai essayé de lire des pages comme celle-ci sur le site JSDoc http://usejsdoc.org/howto-commonjs-modules.html , mais elle ne décrit que les cas de foo.bar, pas foo.bar.baz.

38
machineghost

Vous pouvez utiliser une combinaison de @module ou @namespace avec @memberof .

define([], function() {

    /**
     * A test module foo
     * @version 1.0
     * @exports mystuff/foo
     * @namespace foo
     */
    var foo = {
        /**
         * A method in first level, just for test
         * @memberof foo
         * @method testFirstLvl
         */
        testFirstLvl: function(msg) {},
        /**
         * Test child object with child namespace
         * @memberof foo
         * @type {object}
         * @namespace foo.bar
         */
        bar: {
            /**
             * A Test Inner method in child namespace
             * @memberof foo.bar
             * @method baz
             */
            baz: function() { /*...*/ }
        },
        /**
         * Test child object without namespace
         * @memberof foo
         * @type {object}
         * @property {method} baz2 A child method as property defination
         */
        bar2: {
            /**
             * A Test Inner method
             * @memberof foo.bar2
             * @method baz2
             */
            baz2: function() { /*...*/ }
        },
        /**
         * Test child object with namespace and property def.
         * @memberof foo
         * @type {object}
         * @namespace foo.bar3
         * @property {method} baz3 A child method as property defination
         */
        bar3: {
            /**
             * A Test Inner method in child namespace
             * @memberof foo.bar3
             * @method baz3
             */
            baz3: function() { /*...*/ }
        },
        /**
         * Test child object
         * @memberof foo
         * @type {object}
         * @property {method} baz4 A child method
         */
        bar4: {
             /**
             * The @alias and @memberof! tags force JSDoc to document the
             * property as `bar4.baz4` (rather than `baz4`) and to be a member of
             * `Data#`. You can link to the property as {@link foo#bar4.baz4}.
             * @alias bar4.baz4
             * @memberof! foo#
             * @method bar4.baz4
             */
            baz4: function() { /*...*/ }
        }
    };

    return foo;
});

EDIT selon Commentaire: (Solution d'une seule page pour le module)

bar4 sans cette table de propriété laide. c'est-à-dire @propriété supprimée de bar4.

define([], function() {

    /**
     * A test module foo
     * @version 1.0
     * @exports mystuff/foo
     * @namespace foo
     */
    var foo = {
        /**
         * A method in first level, just for test
         * @memberof foo
         * @method testFirstLvl
         */
        testFirstLvl: function(msg) {},
        /**
         * Test child object
         * @memberof foo
         * @type {object}
         */
        bar4: {
             /**
             * The @alias and @memberof! tags force JSDoc to document the
             * property as `bar4.baz4` (rather than `baz4`) and to be a member of
             * `Data#`. You can link to the property as {@link foo#bar4.baz4}.
             * @alias bar4.baz4
             * @memberof! foo#
             * @method bar4.baz4
             */
            baz4: function() { /*...*/ },
            /**
             * @memberof! for a memeber
             * @alias bar4.test
             * @memberof! foo#
             * @member bar4.test
             */
             test : true
        }
    };

    return foo;
});

Références -

  1. Une autre question sur les espaces de noms imbriqués
  2. Pour une utilisation alternative des namespaces
  3. Documenter des objets littéraux

* Note Je n'ai pas essayé moi-même. S'il vous plaît essayer de partager les résultats.

48
Mohit

Voici un moyen simple de le faire:

/**
 * @module mystuff/foo
 * @version 1.0
 */
define([], function() {

/** @lends module:mystuff/foo */
var foo = {
    /**
     * A method in first level, just for test
     */
    testFirstLvl: function(msg) {},
    /**
     * @namespace
     */
    bar4: {
        /**
         * This is the description for baz4.
         */
        baz4: function() { /*...*/ },
        /**
         * This is the description for test.
         */
        test : true
    }
};

return foo;
});

Notez que jsdoc peut déduire les types baz4.baz4 et test sans avoir à dire @method et @member.

En ce qui concerne jsdoc3, mettre la documentation pour les classes et les espaces de noms sur la page même que le module qui les définit, je ne sais pas comment le faire.

J'utilise jsdoc3 depuis des mois, en documentant une petite bibliothèque et une grande application avec. Je préfère me plier à la volonté de jsdoc3 dans certaines régions que de devoir taper des rames de @-directives pour la plier à ma volonté.

7
Louis

Juste pour améliorer un peu la réponse de Prongs pour JSDoc3 , je n'ai réussi à le faire fonctionner que lorsque j'ai utilisé @instance annotation au lieu de @member .

Exemple de code ES6 suivant:

class Test
{
    /**
     * @param {object} something
     */
    constructor(something)
    {
        this.somethingElse = something;

        /**
         * This sub-object contains all sub-class functionality.
         *
         * @type {object}
         */
        this.topology = {
            /**
             * Informative comment here!
             *
             * @alias topology.toJSON
             * @memberof! Test#
             * @instance topology.toJSON
             * 
             * @returns {object} JSON object
             */
            toJSON()
            {
                return deepclone(privatesMap.get(this).innerJSON);
            },


            ...
        }
    }
}
0
Xunnamius

Vous ne pouvez pas documenter directement les fonctions imbriquées. Je n'aimais pas la solution Prongs, j'ai donc utilisé une implémentation différente sans espaces de noms (c'est JS, not Java!).

Mettre à jour:

J'ai mis à jour ma réponse pour refléter le cas d'utilisation exact donné par l'OP (ce qui est juste, car JSdoc est assez pénible à utiliser). Voici comment cela fonctionnerait:

/** @module foobar */

/** @function */
function foobarbaz() {
    /* 
     * You can't document properties inside a function as members, like you
     * can for classes. In Javascript, functions are first-class objects. The
     * workaround is to make it a @memberof it's closest parent (the module).
     * manually linking it to the function using (see: {@link ...}), and giving
     * it a @name.
     */

    /**
     * Foo object (see: {@link module:foobar~foobarbaz})
     * @name foo
     * @inner
     * @private
     * @memberof module:foobar
     * @property {Object} foo - The foo object
     * @property {Object} foo.bar - The bar object
     * @property {function} foo.bar.baz - The baz function
     */
    var foo = {

        /* 
         * You can follow the same steps that was done for foo, with bar. Or if the
         * @property description of foo.bar is enough, leave this alone. 
         */
        bar: {

            /*
             * Like the limitation with the foo object, you can only document members 
             * of @classes. Here I used the same technique as foo, except with baz.
             */

            /**
             * Baz function (see: {@link module:foobar~foo})
             * @function
             * @memberof module:foobar
             * @returns {string} Some string
             */
            baz: function() { /*...*/ }
        }
    };

    return foo;
}

Malheureusement, JSdoc est un portage de Java. Il comporte donc de nombreuses fonctionnalités utiles pour Java mais pas pour JS, et inversement. Par exemple, étant donné que les fonctions JS sont des objets de première classe, elles peuvent être traitées comme des objets ou des fonctions. Donc, faire quelque chose comme ça devrait marcher:

/** @function */
function hello() {
  /** @member {Object} */
  var hi = {};
}

Mais ce ne sera pas le cas, car JSdoc le reconnaît comme une fonction. Vous devez utiliser des espaces de noms, ma technique avec @link, ou en faire une classe:

/** @class */
function Hello() {
  /** @member {Object} */
  var hi = {};
}

Mais cela n’a aucun sens non plus. _ {Les classes existent-elles dans JS?} _ Non, ce n'est pas le cas. 

Je pense que nous devons vraiment trouver une meilleure solution de documentation. J'ai même constaté des incohérences dans la documentation concernant l'affichage des types (par exemple {object} vs {Object}).

Vous pouvez également utiliser ma technique pour documenter les fermetures .

0
risto