Как использовать 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
.
Ответы
Ответ 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;
});
Рекомендации -
- Другой вопрос о вложенных пространствах имен
- Для альтернативного способа использования пространств имен
- Документирование литеральных объектов
* Обратите внимание, я не пробовал сам. Пожалуйста, попробуйте поделиться результатами.
Ответ 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);
},
...
}
}
}