简体   繁体   English

如何使用jsdoc 3或jsdoc记录Require.js(AMD)模块?

[英]How to document a Require.js (AMD) Modul with jsdoc 3 or jsdoc?

I have 2 types of Modules: 我有两种类型的模块:

Require.js Main File : 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) {
      }
    );

Mediator Pattern: 调解员模式:

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;

});

How can i document this with jsdoc3 when possible with jsdoc too? 如果可能的话,我怎么能用jsdoc3记录这个?

This is my first answer on SO, please let me know how I can improve future answers. 这是我在SO上的第一个答案,请让我知道如何改进未来的答案。

Your specific example 你的具体例子

I've been searching for an answer for this for a good two days, and there doesn't seem to be a way to document RequireJS AMD modules automatically without some redundancy (like repeated function names). 我一直在寻找一个好的两天的答案,并且似乎没有办法自动记录RequireJS AMD模块而没有一些冗余(如重复的函数名称)。 Karthrik's answer does a good job of generating the documentation, but if something gets renamed in the code the documentation will still be generated from what's in the jsDoc tags. Karthrik的答案很好地生成了文档,但是如果在代码中重命名了某些内容,那么仍然会从jsDoc标记中的内容生成文档。

What I ended up doing is the following, which is adjusted from Karthik's example. 我最终做的是以下内容,这是根据Karthik的例子进行调整的。 Note the @lends tag on line 1, and the removal of the @name tag from the jsDoc comment blocks. 注意第1行的@lends标记,以及从jsDoc注释块中删除@name标记。

 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;

});

From what I understand, the @lends tag will interpret all jsDoc comments from the next following object literal as part of the class referenced by the @lends tag. 根据我的理解, @lends标记将解释来自下一个对象文字的所有jsDoc注释,作为@lends标记引用的类的一部分。 In this case the next object literal is the one beginning with function(Mediator) { . 在这种情况下,下一个对象文字是以function(Mediator) {开头的文字。 The @name tag is removed so that jsDoc looks in the source code for function names, etc. 删除@name标记,以便jsDoc在源代码中查找函数名称等。

Note: I've used the @exports tag at the same place as where I put the @lends tag. 注意:我在@exports标记的同一位置使用了@lends标记。 While that works, it'll create a module in the docs… and I only wanted to generate docs for the class. 虽然这有效,但它会在文档中创建一个模块......我只想为该类生成文档。 This way works for me! 这种方式适合我!

General jsDoc references 一般jsDoc参考

jsDoc doesn't seem to like the "define" and "require" calls. jsDoc似乎不喜欢“define”和“require”调用。

So, we ended up using multiple tags to make the jsDoc tool to pick up the constructor and other specific class methods. 因此,我们最终使用多个标记来使jsDoc工具获取构造函数和其他特定的类方法。 Please have a look at the example below: I have just copy-pasted from my source-code and replaced it with your class name and method names. 请看下面的示例:我刚从源代码中复制粘贴,并将其替换为您的类名和方法名。 Hope it works for you. 希望对你有效。

    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;

    });

Note: The above method of documenting JS-code worked out well for us while using jsDoc. 注意:使用jsDoc时,上面记录JS代码的方法对我们来说效果很好。 Haven't got a chance to try jsDoc3. 没有机会尝试jsDoc3。

Taking the link from Muxa's answer , we see that the documentation does specifically refer to RequireJS: 从Muxa的答案中获取链接 ,我们看到文档特别提到RequireJS:

The RequireJS library provides a define method that allows you to write a function to return a module object. RequireJS库提供了一个define方法,允许您编写函数以返回模块对象。 Use the @exports tag to document that all the members of an object literal should be documented as members of a module. 使用@exports标记来记录对象文字的所有成员都应记录为模块的成员。

Module Example 模块示例

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

So in the above example, we see that jsdoc will parse a my/shirt module and document it as having two members: a property color , and also a class Turtleneck . 所以在上面的例子中,我们看到jsdoc将解析my/shirt 模块并将其记录为具有两个成员:属性color ,以及类Turtleneck The Turtleneck class will also be documented as having it's own property size . Turtleneck类也将被记录为具有自己的属性size

Constructor Module Example 构造函数模块示例

Use the @alias tag simplify documenting a constructor-module in RequireJS. 使用@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;
});

The above is what you'd want to use if you are exporting a constructor function as the module which will be used as a class to instantiate objects. 如果要将构造函数导出为将用作实例化对象的类的模块,则上面是您要使用的内容。 To sum up, I'm not sure about using the @lends and other tags/techniques that have been recommended. 总而言之,我不确定是否使用了@lends和其他标签/技术。 Instead, I would try to stick with the @module , @exports , and @alias tags used in the documentation referencing RequireJS . 相反,我会尝试坚持引用RequireJS文档中使用的@module@exports@alias标记。

I'm not sure how you should document your requirejs 'main' file. 我不确定你应该如何记录你的requirejs'main'文件。 If I understand correctly, you are not actually defining any module there, but rather executing a one off function which depends on several modules. 如果我理解正确,你实际上并没有在那里定义任何模块,而是执行依赖于几个模块的一次性函数。

My AMD classes use a slightly different form, but JSDoc wasn't documenting them either so I thought I'd share what worked for me. 我的AMD类使用稍微不同的形式,但JSDoc也没有记录它们,所以我想我会分享对我有用的东西。

Constructors in the global namespace are automatically added: 全局命名空间中的构造函数会自动添加:

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

If you want this behavior on a constructor inside an AMD module, declare it either as global or a member of a namespace : 如果要在AMD模块内的构造函数上使用此行为,请将其声明为全局命名空间成员

define([], function() {
/**
* @classdesc This won't be automatically documented unless you add memberof,
* because it's inside another function.
* @constructor
* @memberof Namespace
*/
function TestClassNamespace() {
}

/**
* @classdesc This won't be automatically documented unless you add global,
* because it's inside another function.
* @constructor
* @global
*/
function TestClassForcedGlobal() {
}
});

Looks like things have gotten a lot simpler in JSDoc3. 看起来JSDoc3中的事情变得更加简单了。 The following worked for me: 以下对我有用:

Mediator as a module Mediator作为一个模块

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

});

However, I would probably make the following change to the code: 但是,我可能会对代码进行以下更改:

/**
 * Mediator Module
 * @module Package/Mediator
 */
define([], function(){

  var channels = {};
  var Mediator = {}

  ...

Reason is, the module says it defines Mediator , but seems to borrow from some other instance of Mediator . 原因是,模块说它定义了Mediator ,但似乎是从Mediator其他一些实例借用的。 I'm not sure I understand that. 我不确定我明白这一点。 In this version, it's clear Mediator is defined by this file and exported. 在这个版本中,很明显Mediator是由这个文件定义并导出的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM