Tuesday, September 27, 2011

Quick practical introduction to JSDoc (JsDoc Toolkit)

Documentation of JavaScript code is a very important part of software development and helps front-end developers to understand code of third-party libraries. There are really well documented libraries. One of them is Mojarra JavaScript documentation. Other libraries (and that's a common case) don't have JavaScript documentation at all or don't cover all their features, so that features stay undocumented (I hope PrimeFaces guys read this blog post :-)).

JSDoc is documentation generated for JavaScript code by means of JsDoc Toolkit. Documentation is not restricted to multi-page HTML, other formats are possible too. Look-&-feel can be fully customized by templates. In this quick introduction I use built-in templates and would like to show generated JSDoc on example of my open source project "Collaborative Online-Whiteboard". I use following tags in my example:

@fileOverview
This tag allows you to provide documentation for an entire file. It's often used with other tags @author and @version.
@class
This tag also allows you to add a description of the JavaScript class (if you write your code in OOP style).
@param
This tag allows you to document information about the parameters to a function, method or class (constructor)
@public
This tag allows you to document public methods or variables.
@private
This tag allows you to document private methods or variables.
@type
This tag allows you to document the type of value a variable refers to, or the type of value returned by a function.
@returns
This tag documents the value returned by a function or method. You can specify a type of the returned value in curly braces {...}.
@link
This tag allows you to create a HTML link to some other documented symbol (similar link in JavaDoc).

Let's document the JavaScript code! I have a class called WhiteboardDesigner which expects 5 parameters (to be passed to constructor) and has many public / private methods. The documented class looks like
/**
* @fileOverview
* @author <a href="mailto:ovaraksin@googlemail.com">Oleg Varaksin</a>
* @version 0.2
*/

/**
* Whiteboard designer class for element drawing.
* @class
* @param witeboardConfig whiteboard's configuration {@link WhiteboardConfig}
* @param whiteboardId whiteboard's id
* @param user user (user name) working with this whiteboard
* @param pubSubUrl URL for bidirectional communication
* @param pubSubTransport transport protocol "long-polling" | "streaming" | "websocket"
*/
WhiteboardDesigner = function(witeboardConfig, whiteboardId, user, pubSubUrl, pubSubTransport) {
    /**
     * Whiteboard's configuration {@link WhiteboardConfig}.
     * @public
     * @type WhiteboardConfig
     */
    this.config = witeboardConfig;
    /**
     * Whiteboard's id.
     * @public
     * @type uuid
     */    
    this.whiteboardId = whiteboardId;
    /**
     * User which works with this whiteboard.
     * @public
     * @type string
     */    
    this.user = user;
    /**
     * URL for bidirectional communication.
     * @public
     * @type string
     */    
    this.pubSubUrl = pubSubUrl;
    /**
     * Transport protocol "long-polling" | "streaming" | "websocket".
     * @public
     * @type string
     */    
    this.pubSubTransport = pubSubTransport;
    /**
     * Logging flag, true - logging is visible, false - otherwise.
     * @public
     * @type boolean
     */    
    this.logging = false;
    /**
     * Raphael's canvas.
     * @private
     * @type Raphael's paper
     */    
    var paper = Raphael(this.config.ids.whiteboard, whiteboard.width(), whiteboard.height());
    
    ...
    
    /** Draws image with default properties.
    * @public
    * @param inputUrl image URL.
    * @param width image width.
    * @param height image height.
    */    
    this.drawImage = function(inputUrl, width, height) {
        ...
    }
    
    /** Gets currently selected whiteboard element.
    * @public
    * @returns {Raphael's element} currently selected element
    */
    this.getSelectedObject = function() {
        ...
    }

    ...

    /** Outputs debug messages.
    * @private
    * @param msg message
    */
    var logDebug = function(msg) {
        ...
    }
}
How to generate a documentation now? I would like to show a quick and simple way. Download JsDoc Toolkit zip file at first. Extract it and go to the directory jsdoc-toolkit. Create there a new folder with any name which will contain your documented JavaScript files. I have created a folder called "whiteboard". Copy all JavaScript files into this folder. Open a DOS console or Linux terminal or whatever at jsdoc-toolkit and type
 
java -jar jsrun.jar app/run.js -a -p -t=templates/jsdoc ./<yours folder name>/*.*
 
In my case it's
 
java -jar jsrun.jar app/run.js -a -p -t=templates/jsdoc ./whiteboard/*.*
 
JsDoc Toolkit runs via the Mozilla JavaScript Engine "Rhino." Rhino is wrapped in a runner application called jsrun. Option -a says: include all functions, even undocumented ones. Option -p says: include symbols tagged as private, underscored and inner symbols (such symbols are not included per default). Option -t is required und used to point to templates for output formatting. Using of default build-in templates which are located under templates/jsdoc is satisfying in most cases.

After script running you will find generated files in the out folder. Entry file is index.html. Its location is .../jsdoc-toolkit/out/index.html You can see online here how does it look for my project. Have much fun!

8 comments:

  1. Hi,

    Thats a nice post. I have a question. When i run the tool against a js file say "praveen.js", i want the output file in the name praveen.html, but the tool gives me file with name _global_.html. any ideas on that?

    ReplyDelete
    Replies
    1. you have to include the attribute @class at the beginning in your js file, otherwise it is going to create the _global_.html file

      Delete
  2. I think output file can be configured. Have you looked into JSDoc documentation? I can't remember at the moment.

    ReplyDelete
  3. Great post. I found this being very useful for introduction to this jsDoc kit. Thanks!

    ReplyDelete
  4. i used the same steps and the file u mentioned above but i am not getting the same HTML output, instead i am just getting a template which i guess already exists for index.html

    ReplyDelete
  5. Documenting of JavaScript code is almost like testing which should be known by everyone who deals with it. Actually there are various ways to documentation but I prefer to use YUIDoc which is a app based on comments.

    ReplyDelete
  6. I prefer JSDuck, because it looks really great. See http://enepomnyaschih.github.io/jwidget

    Can JSDoc or any other generator deal with generic types, like MyList?

    Can the same annotations be used to perform semantic validation of the code somehow?

    ReplyDelete

Note: Only a member of this blog may post a comment.