Documenting a class in an AMD module with JSDoc 3 - javascript

I'm trying to document a class in an AMD JavaScript module using JSDoc 3. Here's my code, based on the example in the documentation here:
/**
* A module representing a jacket.
* #module my/jacket
*/
define('my/jacket', function() {
/**
* #class
* #alias module:my/jacket
*/
function Jacket() {
}
/**
* Open and close your Jacket.
*/
Jacket.prototype.zip = function() {
};
return Jacket;
});
The output this produces looks like this:
Class: module:my/jacket
module:my/jacket
new module:my/jacket()
but I'd like it to read:
Class: Jacket
Jacket
new Jacket()
Is there a way to do this? I'm using jsdoc 3.4.1.
I've tried changing #class to #class Jacket, which almost works: the class appears with the right name, but the documentation of the zip method is not generated.

The solution was to set the class (function) name using the #alias tag instead of the module name:
/**
* A module representing a jacket.
* #module my/jacket
*/
define('my/jacket', function() {
/**
* #class
* #alias Jacket
*/
function Jacket() {
}
/**
* Open and close your Jacket.
*/
Jacket.prototype.zip = function() {
};
return Jacket;
});
This produces the desired output:
Class: Jacket
Jacket
new module:Jacket()
together with the zip method documentation.

Related

How can get VS Code Intellisense to recognize JSDoc annotations?

How should I document the below code so that it would work with vscode Intellisense to get all the methods to show?
I have tried various combination of #class, #typedef above TMCharacter.Character but it didn't work like I expected it to. Intellisense still recognize my_char as type any.
/** #namespace */
var TMCharacter = {}
TMCharacter.Character = cc.Sprite.extend({
ctor: function(spritename){
cc.Sprite.prototype.ctor.call(this, spritename);
this.setupCharacter();
},
onEnter: function(){
this._super();
},
/**
* Setup the components for the characters
* #method
*/
setupCharacter: function(){
// do stuff
}
});
/** #type {TMCharacter.Character} */
var my_char = new TMCharacter.Character(sprite)

AMD + Backbone + JSDoc3 best way to document

I'm looking for the best way to document my code, but I don't find anything.
I've see others topics, including this, but there all doesn't resolve my problem.
I have something like this:
define([
'backbone'
], function (Backbone) {
/**
* #module models/products
*/
/**
* Product model
* #class
*/
var Product = Backbone.Model.extend({
/** #lends Product.prototype */
/**
* Some method
* #param {String} name - Name of something
* #return {something}
*/
someMethod: function () {
// ...
}
});
/**
* Products collection
* #class
*/
var Products = Backbone.Collection.extend({
/** #lends Products.prototype */
/**
* #type {Product}
*/
model: Product,
/**
* Some method
* #param {String} name - Name of something
* #return {something}
*/
someMethod: function () {
// ...
}
});
return Products;
});
I need to generate a legible documentation, where Product and Products classes apears into the models/products module, but I get the module clear and the classes by separate.
I suppose there is someone who has gone through this issue.
Thanks.
PD1: I really read other posts, I'm not trying to duplicate questions.
PD2: Sorry my poor english :S
After reading this doc, I understand that your problem can be solved by moving the following code to the top of the file:
/**
* #module models/products
*/
I understand that since you have written #module inside a anonymous function its just get ignored.

Documenting a private constructor with JSDoc

I've got a class where individual methods may be called statically but will return a new instance of class in order to chain, for example:
var builder = ns
.setState('a', 'A')
.setState('b', 'B');
Where Builder is defined as such:
/**
* #module Builder
*/
/**
* #class Builder
*/
/**
* #private
*/
function Builder() {
this.state = {
query: {}
};
}
Builder.prototype = {
/**
* #param {string} k - The key
* #param {object} v - The value
* #return {Builder}
*/
setState: function(k, v) {
var that = (this instanceof Builder) ? this : new Builder();
that[k] = v;
return that;
}
// Other properties and methods…
}
The Builder constructor is never supposed to be called explicitly by user code and thus I'd like it not to show up in the docs. However, all of the combinations I've tried with JSDoc tags (e.g. #private, #constructs, etc.) can't seem to suppress it from the built docs.
From version 3.5.0 of jsDoc, you can use tag #hideconstructor on the class, telling jsDoc not to include the constructor into documentation.
/**
* #class Builder
*
* #hideconstructor
*/
function Builder() {
// implementation
}
You should be able to use the #ignore directive to achieve this. From the docs:
The #ignore tag indicates that a symbol in your code should never appear in the documentation. This tag takes precedence over all others.
http://usejsdoc.org/tags-ignore.html

Modules and classes using JSDoc + RequireJS + BackboneJS

I'm trying to create a documentation for my system but something's always wrong.
In the following, my Class appear in the module MyModule, perfect! But my function doesn't appear in the documentation!
Do you have any idea where the problem is coming from?
define([
'underscore',
'backbone'
], function(_, Backbone) {
'use strict';
/**
* MyModule
*
* #module MyModule
*/
var MyModule = {};
/**
* Class description
*
* #class MyModule.View
* #extends Backbone.View
* #memberOf module:MyModule
* #abstract
*/
MyModule.View = Backbone.View.extend(
/** #lends MyModule.View */
{
/**
* myFunction1
*
* #param {object} hello Hello World!
*/
myFunction1: function(hello) { }
}
});
/**
* Class description
*
* #class MyModule.Model
* #extends Backbone.Model
* #memberOf module:MyModule
* #abstract
*/
MyModule.Model = Backbone.Model.extend();
//etc...
});
Thanks
You have to prefix the name passed to #lends with the module name. See the #lends statement in this snipped I adapted from the code in your question:
MyModule.View = Backbone.View.extend(
/** #lends module:MyModule.MyModule.View */
{
/**
* myFunction1
*
* #param {object} hello Hello World!
*/
myFunction1: function(hello) { }
});
With the #lends above, I'm able to get myFunction1 to show up, properly documented.

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

I have 2 types of Modules:
Require.js Main File:
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?
This is my first answer on SO, please let me know how I can improve future answers.
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.
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.
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.
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!
General jsDoc references
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 doesn't seem to like the "define" and "require" calls.
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.
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.
Taking the link from Muxa's answer, we see that the documentation does specifically refer to 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.
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. The Turtleneck class will also be documented as having it's own property size.
Constructor Module Example
Use the #alias tag simplify documenting a constructor-module in 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. Instead, I would try to stick with the #module, #exports, and #alias tags used in the documentation referencing 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.
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.
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:
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. The following worked for me:
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.

Categories

Resources