I’ve been using JSDuck to generate log4js-ext documentation, and I’m quite happy with it.
It allowed me to generate the log4js-ext API documentation in a day, and I had to learn how to use it and decide some baseline practices in that time.
These notes are relative to JSDuck 3.11.0, and include some practices, doubts and precautions I consider relevant.
BTW, the list of tags JSDuck supports is here.
Important practices -at least to me!
-
Data types: this is key, because javascript is not type safe and sometimes the type is not evident
-
Always specify the type for parameters, return values and properties.
This is usually done writing{xxx}
somewhere, where xxx is the type (String
,Array
,Sm.log.Logger
,etc.). -
If something can have several types, use this notation:
{String/Sm.log.Logger}
, with ‘/’ separating several alternative types. -
If you want to refer to the special
arguments
variable, you can define its type as{Arguments}
. -
Always add
@returns {void}
to functions that returns nothing. Else, you never know whether there is no type because the function returns nothing, or you forgot to specify it.
-
Always specify the type for parameters, return values and properties.
-
Statics:
-
You must always add the
@static
tag by hand, even though you are commenting something instatics
: else, the static member will appear as an instance member. -
You must specify
@property
explicitly for statics, or they will appear as a global, instead of appearing as part of a class. Bug?
-
You must always add the
-
If you are using the
config
thing in ExtJs based code:-
You must explicitly add the
@cfg
tag, or else the item will be signaled as a property, not a config. -
To get getter/setter doc you must add the
@accessor
explicitly.
Unfortunately, if aconfig
entry is not marked with@cfg
, there is no documentation generated for getters/setters. -
If you have an item for which you don’t want a setter, create documentation for the setter and make it private.
As explained below, you can create documentation for an item even if you don’t declare it explicitly. -
Mark the config as required if needed: you do this by writing something like
@cfg (required)
-
You must explicitly add the
-
Always add the
@readonly
tag where appropriate. It is very important because this tells you not to juggle with something. -
Always specify the
@protected
and@private
tags. Because in javascript everything is public, your only way to know about this is the documentation. -
Always specify the
@abstract
tag where appropriate. This will help implementors of derived clases quite a lot. -
In a
@returns
tag, do not start comment in one line and continue in another, or it will not be considered part of the return comment. You can start the comment in the second line, placing the type in the first one. -
To hide a class to documenation, make it
@private
. -
In javascript you can always add a new property or function as you see fit, but, how do you document something you add in the middle of some function?
You can document things that are not declared explicitly like this:/** * @cfg {String} name (required) * A very importand config option that must be specified. */
I have to confess that it feels a bit strange to have comments for a property that is not there, and that I feel better if I provide the property itself, if at all possible. But I have to consider what’s worse, a ‘lonely’ comment or a comment with a property initialized to a fake and posibly wrong value.
Doubts
There are some things I’m not sure how to handle:
-
I’m not sure about how to specify an enumerated type (WARNING, INFO, …).
Maybe the best way is to create a class just for that enumeration, and refer to that class as the type.
I think this is good style, too, so everything should be ok with this approach. - I’m not sure about how to specify optional arguments: for example, in log4js-ext a logger’s logging methods can receive from 1 to n arguments, with very different purpose. I have not decided on a way to document that, beyond providing a link to examples.
-
I miss an additional visibility qualifier, to designate those methods visible only inside a subsystem (package, library, a group of classes…).
Right now I just mark these as private, and add an extra ‘Package’ comment there (which is not visible in the API documentation, unfortunately). -
I’m torn about when to make something private, and when not to document it.
This being javascript, I feel that documenting a private method to the public is almost like telling them that they might use it if they are careful enough, and that to make it really private I should just avoid documenting it.
Huh?
And there are some things that make me wonder if I’m missing something…
-
The
@template
tag, does it really make sense to use it? Its meaning, to me, is equivalent to implying that a certain function is overridable, but, is not that the case for functions,
by default?
Checking everything is ok
Once you’ve generated API doc, you’ll want to:
- Take a look at warnings -though JSDuck generates a lot.
- Look for the ‘unknown type’ string in JSDuck output!
- Take a look at the API doc page with all your classes, and look for spurious globals.
-
In some cases, I’ve got warnings about missing images…that were there.
When checking warnings, make sure that they are for real. - One of these days I will create doc that includes the ExtJs doc itself, so that the user can check whatever he wants *and* I do not get a thousand ‘class not found’ messages when generating the doc.