Подтвердить что ты не робот

Как использовать JSDoc A вложенные методы?

Я пытаюсь использовать JSDoc3 для создания документации по файлу, но у меня есть некоторые трудности. Файл (который является модулем Require.js) в основном выглядит следующим образом:

define([], function() {

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

    return foo;
}

Проблема в том, что я не могу получить baz для отображения в сгенерированной документации. Вместо этого я просто получаю файл документации для модуля foo/foo, в котором указан член bar, но bar не имеет baz (только ссылку на foo исходный код).

Я попытался изменить директиву bar на @property вместо этого, и я попытался изменить директиву baz на @member или @property, но ничто из этого не помогает. Независимо от того, что я делаю, баз просто не хочет появляться.

Кто-нибудь знает, какую структуру директив я могу использовать, чтобы база появилась в сгенерированной документации?

P.S. Я пробовал читать страницы, подобные этому на сайте JSDoc http://usejsdoc.org/howto-commonjs-modules.html, но он описывает только случаи foo.bar, а не foo.bar.baz.

4b9b3361

Ответ 1

Вы можете использовать комбинацию @module или @namespace вместе с @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;
});

РЕДАКТИРОВАТЬ согласно комментарию: (одностраничное решение для модуля)

bar4 без этой уродливой таблицы свойств. т.е. @property удален из 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;
});

Рекомендации -

  1. Другой вопрос о вложенных пространствах имен
  2. Для альтернативного способа использования пространств имен
  3. Документирование литеральных объектов

* Обратите внимание, я не пробовал сам. Пожалуйста, попробуйте поделиться результатами.

Ответ 2

Вот простой способ сделать это:

/**
 * @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;
});

Обратите внимание, что jsdoc может выводить типы baz4.baz4 и test, не указывая @method и @member.

Поскольку jsdoc3 размещает документацию для классов и пространств имен на той же странице, что и модуль, который их определяет, я не знаю, как это сделать.

Я использую jsdoc3 в течение нескольких месяцев, документируя небольшую библиотеку и большое приложение с ней, Я предпочитаю сгибать jsdoc3 в некоторых областях, чем набирать reams @-directives, чтобы согнуть его по моей воле.

Ответ 3

Вы не можете документировать вложенные функции напрямую. Мне не понравилось решение Prongs, поэтому я использовал другую реализацию без пространств имен (это JS, не Java!).

Update:

Я обновил свой ответ, чтобы отразить точный пример использования, предоставленный OP (что справедливо, поскольку JSdoc довольно болезнен для использования). Вот как это работает:

/** @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 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;
}

К сожалению, JSdoc - это порт Java, поэтому он имеет множество функций, которые имеют смысл для Java, но не для JS, и наоборот. Например, поскольку в JS-функциях есть объекты первого класса, их можно рассматривать как объекты или функции. Так что работа над этим должна работать:

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

Но это не так, потому что JSdoc распознает его как функцию. Вам нужно будет использовать пространства имен, мою технику с @link или сделать ее классом:

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

Но тогда это тоже не имеет смысла. Существуют ли классы в JS? нет, они этого не делают.

Думаю, нам действительно нужно найти лучшее решение для документации. Я даже видел несоответствия в документации по тому, как должны отображаться типы (например, {object} vs {object}).

Вы также можете использовать мою технику для документирования закрытий.

Ответ 4

Просто, чтобы улучшить Prongs, немного ответьте на JSDoc3, я смог заставить его работать, когда я использовал @instance аннотация вместо @member.

Пример кода ES6:

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);
            },


            ...
        }
    }
}