Как документировать модуль Require.js(AMD) с помощью jsdoc 3 или jsdoc?
У меня есть 2 типа модулей:
Основной файл Require.js:
require.config({
baseUrl: "/another/path",
paths: {
"some": "some/v1.0"
},
waitSeconds: 15,
locale: "fr-fr"
});
require( ["some/module", "my/module", "a.js", "b.js"],
function(someModule, myModule) {
}
);
Посредник:
define([], function(Mediator){
var channels = {};
if (!Mediator) Mediator = {};
Mediator.subscribe = function (channel, subscription) {
if (!channels[channel]) channels[channel] = [];
channels[channel].push(subscription);
};
Mediator.publish = function (channel) {
if (!channels[channel]) return;
var args = [].slice.call(arguments, 1);
for (var i = 0, l = channels[channel].length; i < l; i++) {
channels[channel][i].apply(this, args);
}
};
return Mediator;
});
Как я могу документировать это с помощью jsdoc3, когда это возможно, с помощью jsdoc?
Ответы
Ответ 1
Это мой первый ответ на SO, пожалуйста, дайте мне знать, как я могу улучшить будущие ответы.
Ваш конкретный пример
Я искал ответ на этот вопрос в течение двух хороших дней, и, похоже, нет возможности автоматически документировать модули RequireJS AMD без некоторой избыточности (например, повторных имен функций). Ответ Karthrik хорошо справляется с созданием документации, но если что-то переименовывается в код, документация будет по-прежнему генерироваться из того, что в тегах jsDoc.
То, что я закончил, - это следующее, которое настроено на примере Karthik. Обратите внимание на тег @lends
в строке 1 и удаление тега @name
из блоков комментариев jsDoc.
define([], /** @lends Mediator */ function(Mediator){
/**
* Mediator class
* This is the interface class for user related modules
* @class Mediator
*/
var channels = {};
if (!Mediator) Mediator = {};
/**
* .... description goes here ...
* @function
*
* @param {Number} channel .....
* @param {String} subscription ..............
* @example
* add the sample code here if relevent.
*
*/
Mediator.subscribe = function (channel, subscription) {
if (!channels[channel]) channels[channel] = [];
channels[channel].push(subscription);
};
Mediator.publish = function (channel) {
if (!channels[channel]) return;
var args = [].slice.call(arguments, 1);
for (var i = 0, l = channels[channel].length; i < l; i++) {
channels[channel][i].apply(this, args);
}
};
return Mediator;
});
Из того, что я понимаю, тег @lends
будет интерпретировать все комментарии jsDoc из следующего следующего литерала объекта как часть класса, на который ссылается тег @lends
. В этом случае следующий литерал объекта - это тот, который начинается с function(Mediator) {
. Тег @name
удаляется, так что jsDoc ищет исходный код для имен функций и т.д.
Примечание. Я использовал тег @exports
в том же месте, где я положил тег @lends
. В то время как это работает, он создаст модуль в документах... и я хотел только создать документы для этого класса. Этот способ работает для меня!
Общие ссылки jsDoc
Ответ 2
jsDoc, похоже, не похож на вызовы "define" и "require".
Итак, мы закончили использование нескольких тегов, чтобы заставить jsDoc-инструмент забрать конструктор и другие специальные методы класса. Пожалуйста, ознакомьтесь с приведенным ниже примером:
Я только что скопировал его из исходного кода и заменил его именами и именами классов. Надеюсь, это сработает для вас.
define([], function(Mediator){
/**
* Mediator class
* This is the interface class for user related modules
* @name Mediator
* @class Mediator
* @constructor
* @return Session Object
*/
var channels = {};
if (!Mediator) Mediator = {};
/**
* .... description goes here ...
* @name Mediator#subscribe
* @function
*
* @param {Number} channel .....
* @param {String} subscription ..............
* @example
* add the sample code here if relevent.
*
*/
Mediator.subscribe = function (channel, subscription) {
if (!channels[channel]) channels[channel] = [];
channels[channel].push(subscription);
};
Mediator.publish = function (channel) {
if (!channels[channel]) return;
var args = [].slice.call(arguments, 1);
for (var i = 0, l = channels[channel].length; i < l; i++) {
channels[channel][i].apply(this, args);
}
};
return Mediator;
});
Примечание. Вышеупомянутый метод документирования JS-кода хорошо зарекомендовал себя при использовании jsDoc. У меня нет возможности попробовать jsDoc3.
Ответ 3
Взяв ссылку из ответа Muxa, мы видим, что в документации конкретно говорится о RequireJS:
Библиотека RequireJS предоставляет метод определения, который позволяет вам написать функцию для возврата объекта модуля. Используйте тег @exports для документирования того, что все члены литерала объекта должны быть документированы как члены модуля.
Пример модуля
define('my/shirt', function () {
/**
* A module representing a shirt.
* @exports my/shirt
* @version 1.0
*/
var shirt = {
/** A property of the module. */
color: "black",
/** @constructor */
Turtleneck: function(size) {
/** A property of the class. */
this.size = size;
}
};
return shirt;
});
Итак, в приведенном выше примере мы видим, что jsdoc будет анализировать модуль my/shirt
и документировать его как имеющий два члена: свойство color
, а также класс Turtleneck
. Класс Turtleneck
также будет документирован как имеющий собственное свойство size
.
Пример модуля конструктора
Использование тега @alias упрощает документирование конструктор-модуля в RequireJS.
/**
* A module representing a jacket.
* @module jacket
*/
define('jacket', function () {
/**
* @constructor
* @alias module:jacket
*/
var exports = function() {
}
/** Open and close your Jacket. */
exports.prototype.zip = function() {
}
return exports;
});
Вышеупомянутое то, что вы хотели бы использовать, если вы экспортируете функцию-конструктор в качестве модуля, который будет использоваться как класс для создания объектов. Подводя итог, я не уверен в использовании @lends
и других тегов/методов, которые были рекомендованы. Вместо этого я попытался бы придерживаться тегов @module
, @exports
и @alias
, используемых в документации, ссылающейся на RequireJS.
Я не уверен, как вы должны документировать свой основной файл requirejs. Если я правильно понимаю, вы на самом деле не определяете какой-либо модуль там, а выполняете одну функцию, которая зависит от нескольких модулей.
Ответ 4
Мои классы AMD используют немного другую форму, но JSDoc не документировал их, поэтому я решил поделиться тем, что сработало для меня.
Конструкторы в глобальном пространстве имен автоматически добавляются:
/**
* @classdesc This class will be documented automatically because it is not in
* another function.
* @constructor
*/
function TestClassGlobal() {
/**
* This is a public method and will be documented automatically.
*/
this.publicMethod = function() {
};
}
Если вы хотите, чтобы это поведение было конструктором внутри модуля AMD, объявите его либо глобальным, либо членом пространства имен:
define([], function() {
/**
* @classdesc This won't be automatically documented unless you add memberof,
* because it inside another function.
* @constructor
* @memberof Namespace
*/
function TestClassNamespace() {
}
/**
* @classdesc This won't be automatically documented unless you add global,
* because it inside another function.
* @constructor
* @global
*/
function TestClassForcedGlobal() {
}
});
Ответ 5
Похоже, в JSDoc3 все стало намного проще. Для меня работали следующие:
Посредник как модуль
/**
* Mediator Module
* @module Package/Mediator
*/
define([], function(Mediator){
var channels = {};
if (!Mediator) Mediator = {};
/**
* Subscribe
* @param {String} channel Channel to listen to
* @param {Function} subscription Callback when channel updates
* @memberOf module:Package/Mediator
*/
Mediator.subscribe = function (channel, subscription) {
if (!channels[channel]) channels[channel] = [];
channels[channel].push(subscription);
};
/**
* Publish
* @param {String} channel Channel that has new content
* @memberOf module:Package/Mediator
*/
Mediator.publish = function (channel) {
if (!channels[channel]) return;
var args = [].slice.call(arguments, 1);
for (var i = 0, l = channels[channel].length; i < l; i++) {
channels[channel][i].apply(this, args);
}
};
return Mediator;
});
Однако, я бы, вероятно, внес следующее изменение в код:
/**
* Mediator Module
* @module Package/Mediator
*/
define([], function(){
var channels = {};
var Mediator = {}
...
Причина в том, что модуль говорит, что он определяет Mediator
, но, похоже, заимствует из другого экземпляра Mediator
. Я не уверен, что понимаю это. В этой версии ясно, что Mediator
определяется этим файлом и экспортируется.