javascript 如何使用 jsdoc 3 或 jsdoc 记录 Require.js (AMD) 模块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10172381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to document a Require.js (AMD) Modul with jsdoc 3 or jsdoc?
提问by 3logy
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 记录这个?
回答by marcusstenbeck
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). 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.
两天来,我一直在为此寻找答案,似乎没有一种方法可以在没有冗余的情况下自动记录 RequireJS AMD 模块(例如重复的函数名称)。Karthrik 的回答在生成文档方面做得很好,但是如果代码中的某些内容被重命名,文档仍将根据 jsDoc 标签中的内容生成。
What I ended up doing is the following, which is adjusted from Karthik's example. Note the @lends
tag on line 1, and the removal of the @name
tag from the jsDoc comment blocks.
我最终做的是以下内容,根据 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;
});
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. In this case the next object literal is the one beginning with function(Mediator) {
. The @name
tag is removed so that jsDoc looks in the source code for function names, etc.
据我了解,该@lends
标签会将下一个以下对象文字中的所有 jsDoc 注释解释为该@lends
标签引用的类的一部分。在这种情况下,下一个对象字面量是以function(Mediator) {
. 该@name
标签使jsDoc看在源代码的函数名,删除等
Note: I've used the @exports
tag at the same place as where I put the @lends
tag. 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!
注意:我@exports
在放置标签的地方使用了@lends
标签。虽然这可行,但它会在文档中创建一个模块……而我只想为类生成文档。这种方式对我有用!
General jsDoc references
一般 jsDoc 参考
- jsdoc-toolkit Tag Reference- Great reference for the tags in jsdoc-toolkit. Has a bunch of examples, too!
- 2ality's jsDoc intro- Comprehensive tutorial based on jsDoc-toolkit.
- jsDoc3 reference- Fairly incomplete, but has some examples.
- jsdoc-toolkit Tag Reference- jsdoc-toolkit 中标签的重要参考。也有一堆例子!
- 2ality 的 jsDoc 介绍- 基于 jsDoc-toolkit 的综合教程。
- jsDoc3 参考- 相当不完整,但有一些例子。
回答by Cory Gross
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. Use the @exports tag to document that all the members of an object literal should be documented as members of a module.
RequireJS 库提供了一个定义方法,允许你编写一个函数来返回一个模块对象。使用@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
moduleand document it as having two members: a property color
, and also a class Turtleneck
. The Turtleneck
class will also be documented as having it's own property size
.
因此,在上面的示例中,我们看到 jsdoc 将解析一个my/shirt
模块并将其记录为具有两个成员:一个 propertycolor
和一个 class Turtleneck
。该Turtleneck
班也将被记录为有它自己的财产size
。
Constructor Module Example
构造函数模块示例
Use the @alias tag simplify documenting a constructor-module in RequireJS.
使用@alias 标记简化在 RequireJS 中记录构造函数模块的过程。
/**
* A module representing a Hymanet.
* @module Hymanet
*/
define('Hymanet', function () {
/**
* @constructor
* @alias module:Hymanet
*/
var exports = function() {
}
/** Open and close your Hymanet. */
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. Instead, I would try to stick with the @module
, @exports
, and @alias
tags used in the documentation referencing RequireJS.
如果您将构造函数导出为将用作实例化对象的类的模块,则上述内容是您想要使用的。总而言之,我不确定使用推荐的@lends
和其他标签/技术。相反,我会尽量坚持用@module
,@exports
以及@alias
在使用标签文件引用RequireJS。
I'm not sure how you should document your requirejs 'main' file. If I understand correctly, you are not actually defining any module there, but rather executing a one off function which depends on several modules.
我不确定你应该如何记录你的 requirejs 'main' 文件。如果我理解正确,您实际上并没有在那里定义任何模块,而是执行依赖于多个模块的一次性功能。
回答by Karthik
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. 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.
所以,我们最终使用了多个标签来让 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;
});
Note: The above method of documenting JS-code worked out well for us while using jsDoc. Haven't got a chance to try jsDoc3.
注意:在使用 jsDoc 时,上述记录 JS 代码的方法对我们来说效果很好。还没有机会尝试 jsDoc3。
回答by Chris
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 globalor 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() {
}
});
回答by Sharadh
Looks like things have gotten a lot simpler in JSDoc3. The following worked for me:
看起来事情在 JSDoc3 中变得简单了很多。以下对我有用:
Mediator as a module
调解器作为一个模块
/**
* 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
. I'm not sure I understand that. In this version, it's clear Mediator
is defined by this file and exported.
原因是,该模块说它定义了Mediator
,但似乎借用了 的其他一些实例Mediator
。我不确定我是否理解。在这个版本中,很明显Mediator
是由这个文件定义并导出的。