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

Как документировать модуль 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?

4b9b3361

Ответ 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

  • jsdoc-toolkit Ссылка на тег - Отличная ссылка на теги в jsdoc-toolkit. Имеет кучу примеров тоже!
  • 2ality jsDoc intro - всесторонний учебник, основанный на jsDoc-инструменталитете.
  • ссылка jsDoc3 - Довольно неполная, но есть некоторые примеры.

Ответ 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 определяется этим файлом и экспортируется.