Friday, May 31, 2013

Creation of documentation for JavaScript library


If you are developing open source library one of most important things is documentation and it's great if it has good design. But anyway, it's better to have a badly designed documentation than none at all.
So here i'll describe of some tectonics (jsdoc, unittests, grunt) to apply documentation for your opensource project.

jsdoc

For javascript we have syntax for adding inline API documentation - it is jsdoc (usejsdoc.org). In general it's based on well know javadoc.

Here are some of jsdoc tags

@author         Developer's name
@constructor    Marks a function as a constructor
@deprecated     Marks a method as deprecated
@exception      Synonym for @throws
@param          Documents a method parameter; 
                a datatype indicator can be 
                added between curly braces
@private        Signifies that a method is private
@return         Documents a return value
@see            Documents an association to another object
@this           Specifies the type of the object to which 
                the keyword "this" refers within a function.
@throws         Documents an exception thrown by a method
@version        Provides the version number of a library
So if anybody will read your sources it's better to annotate it using this kind of traditional style.
/**
 * Build World. Like a Module in AngularJS.
 * w is short form of function world
 * @example
 *<pre>
 var world = darlingjs.world('theWorld', [
   'ngPhysics',
   'ngBox2DEmscripten',
   'ngFlatland',
   'ngPixijsAdapter']);
 *</pre>
 * @param {String} name The name of new World
 * @param {Array} requires The array of requires modules
 *
 * @return {World} The new World;
 */
darlingjs.w = darlingjs.world = function(name, requires) {
...

UnitTest

Another good approach to describe common use cases of library is to share annotated unittests. In javascript we have a lot of unittest libraries for it (jasmine, Mocha, QUnit and so on).
Here is an example of Jasmine unittest
describe('World', function() {
    //...

    it('should execute update handler on update.', function() {
        var updateHandler = sinon.spy();
        darlingjs.module('theModule')
            .$c('theComponent')
            .$system('testSystem', {
                require: ['theComponent'],
                $update: updateHandler
            });

        var world = darlingjs.world('testWorld', ['theModule']);
        world.$add('testSystem');
        world.$update(11);
        expect(updateHandler.calledOnce).toBeTruthy();
        expect(updateHandler.calledWith(11)).toBeTruthy();
    });

    //...
});

grunt

Well-documented and well-tested source code is good. But not all developers have enough will to look through your code to search a needed function. So one level-up trick is to generate web-based documentation. And it's also a good idea to do it automatically any time your code changes.
Here is a plugin for Grunt grunt-jsdoc-plugin for running documentation generator.

Example

So let's look at jsdoc plugin in practice.

Result

darlingjs documentation
darling.js documentation

Gruntfile.js

We need to install and save in package.js file two modules:
jsdoc
npm install grunt-jsdoc --save-dev
Clean
npm install grunt-contrib-clean --save-dev
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        clean: {
            docs: ['docs/']
        },
        jsdoc: {
            src: ['src/core/**/*.js', 
                  'src/utils/**/*.js', 
                  'README.md'],
            options: {
                configure: '.jsdocrc',
                destination: 'docs'
            }
        }
    });

    grunt.registerTask('docs', ['clean', 'jsdoc']);

    grunt.loadNpmTasks('grunt-jsdoc');
    grunt.loadNpmTasks('grunt-contrib-clean');
};

.jsdocrc

Add information about markdown plugin - gfm for parsing github-compatible README.mb. Custom template is just based on default jsdoc template.
{
  "plugins": [ "plugins/markdown" ],
  "markdown": {
    "parser": "gfm",
    "hardwrap": true,
    "githubRepoName": "darlingjs",
    "githubRepoOwner": "hyzhak"
  },
  "opts": {
    "template": "./doc-template"
  }
}

Add Template for jsdoc

For example you can customize layout.tmpl template file to add GoogleAnalytics, some social buttons and Disqus comments as i've done for darling.js.

Are there any other technics?

If you are using some other techniques to create documentation for your projects don't hesitate to share your own experience with other people in comments. You are highly welcome.

Polling




survey software

No comments :

Post a Comment