Categories
Commenting JavaScript code with JSDoc
Last published on January 22, 2016 by Marcos Iglesias
This article was originally posted on the Eventbrite Engineering Blog.
Software developers do not document their code very often, that's especially true for JavaScript. That's a problem when they jump into parts of the code they are not familiar with (or they forgot about) and there are no docs or comments. How can we avoid this? In this post, I will talk about how you can use JSDoc comments to clarify your JavaScript code and generate documentation for it.
My Experience
Some months ago, I spent some time reading a bit about JSDoc. I found it really interesting, so I decided to use JSDoc comments in the next projects I tackled at Eventbrite. Over the last few months, I had the chance to use JSDoc comments in three ‘types’ of codebases that I think represent three different archetypes of code. Let me introduce you to them: I'm breaking it down into The Good, The Bad & The Ugly.
The Good
The good code contains new and shiny code. It is one of those greenfield projects that we, as software developers, LOVE to work with. The structure of it is(still) pretty clean and simple. It is fully tested and may have been written on a TDD basis. Its challenges are that we probably want to open source it, so it needs to keep being clear and simple. The code quality needs to stay high, and it really needs good documentation.
The Bad
This one could be a piece of old, entangled code without any documentation or comments whatsoever. It’s usually challenging code that you really want to get into shape. That implies breaking quite a few dependencies and move some other pieces to the right place. You know, one of those projects whose defects don’t seem to justify a full rewrite, although sometimes you are not sure. It could have some tests, but the test suite is rather incomplete. The challenge of this code is that is easy to get lost in it. There are a number of non-obvious or directly misleading relationships between modules, and it could also feature a high level of indirection.
The Ugly
The Ugly is not essentially old or new code; it’s just complex. Maybe the structure is too elaborate, or it has been optimized for reusability or performance, so it has a really steep learning curve. In my case, the code didn’t have any documentation or comments, although it was fully tested. When working with The Ugly code, you will find a lot of new conceptual elements or new ways of doing things without having a lot of examples to use as a reference. It could also feature a high level of indirection or a complex inheritance hierarchy.
Introducing JSDoc
I commented all of these codebases with JSDoc, but what is this tool? JSDoc is an API documentation generator for JavaScript. It is based on a series of tags (words preceded by a ‘@‘ symbol) that are used before each function or module/class, and that will describe the different characteristics of the code. The inner workings are pretty simple. You just need to add comments to your methods in a given way and run the JSDoc tool. It it will scan the code to generate an HTML documentation website for you.
JSDoc API
Let’s look at the JSDoc tags in more detail. The first block I will show you is a selection of the most common tags used to describe methods or functions:
Function/Method description
- @param
- single type @param {string} name
- multiple types @param {string|number} name
- array of a type @param {string[]} name
- @return
- @private/@public
- @example
- @deprecated
- @link
Of these tags, the most common is the @param tag. It describes an input parameter of the method and it can be a single type (The types are the words between curly braces {}.) like ‘string’, multiple types or an array of one type.
The @return tag will describe whatever the method is returning, and it will also come with a related type. @private and @public are two tags that are useful for defining which methods will be part of the API reference document that we’ll generate with the comments. @example precedes an example of use of the method, @deprecated marks the method as deprecated and @link is useful to create a text link to an external reference.
Let’s see some examples:
/**
* Animation for chart loading
* Check out {@link http://bl.ocks.org/mbostock/4341574| this example}
*
* @param {obj} b Data point
* @return {funct} Tween function
* @private
*/
function tweenLoading(b) {
var i;
b.innerRadius = 0;
i = d3.interpolate({ startAngle: 0, endAngle: 0 }, b);
return function (t) {
return shape(i(t));
};
}
Describing modules with JSDoc looks more or less the same:
Module or Class
- @exports - What is exported
- @fileOverview - Description
- @requires - Dependencies
- @version
The most important tag here is @exports as it is the one that specifies what the file will expose as a result of its parsing. Any code tagged with @fileOverview will have the content of this tag in a highlighted position at the top of the webpage, so this a useful tag to talk about the module’s purpose.
The @requires tag lists the dependencies of the module and @version, well, states the version of it. Let’s look at another example:
/**
* @fileOverview Line Chart reusable API module that allows us
* rendering a multi line and configurable chart.
*
* @exports charts/line
* @requires d3
* @version 0.0.1
*/
return function module(){
You can find more information about the available tags in the official web. Ironically, you may notice that the JSDoc documentation is worse than the JSDoc generated documentation.
Documentation Generation
A great benefit of JSDoc style comments is that they could change the way your organization creates documentation dramatically. This is true due to the chance of generating documentation directly from the code and the comments.
By using a grunt task, grunt-jsdoc, you will be able to generate documentation pages from your commented code. At Eventbrite, we have been exploring two different flavors of it, DocStrap and Docco.
DocStrap is a doc generator that creates markup for the Bootstrap CSS framework and whose main selling point is that it creates configurable API reference pages for the different objects that compose our code. It seems like the best option when we need to create ‘Getting started guides’, ‘Tutorials’ and ‘Demo pages’ as well as the aforementioned API reference page. You can find a good example here.
Docco is a lightweight literate-programming-style documentation generator. Its main characteristic is that it provides a great output for ‘annotated code’ style documentation. Basically, this means we are going to display our code side-by side with comments justifying why the code was written in a particular way. It’s great to explain the decisions that the original developer took to arrive at that particular solution. A good example would be the Marionette annotated code.
It’s important to note that Docco doesn’t use the JSDoc-style comments; it uses a simple ‘//‘ notation to create the ‘prose’ side of the documentation. That means that we can use both flavors at the same time, producing both the ‘annotated code’ output and the ‘API reference’ one.
Improvements in the code
After using JSDoc in my code, I find that each codebase benefitted in a specific way:
The Good
For The Good, using JSDoc favored the creation of small and specific methods. It helped state which methods were public or private, as the commenting process became a sort of deep review of the new code I was writing. With this code, I didn’t only add the comments, I also generated the documentation from them. Using DocStrap, I was able not only to generate an API reference for the public methods of my modules, but also to create demo pages and getting started guides for my project. With The Good code, I ended up with a fully tested and documented project. I had never done something like that and I feel proud of it!
The Bad
Dealing with spaghetti code is every developer's worst nightmare. I managed to extract some methods with some entangled code, and adding descriptions and small footprint explanations has saved me from multiple re-readings of bad looking code. This was good for my retinas! Adding comments also helped me clarify which methods needed a refactor and which ones didn’t even belong to that file. It was also helpful to state the dependencies and links between modules clearly.
The Ugly
I only had one objective when I started commenting the ugly code: I just wanted to understand it so I could keep on working with it. Making the effort to read and comment helped me understand the code better. And as I was not familiar with that code, this meant that I didn’t have to read it twice. Also when commenting those complex blocks of code, I was helping the next person to understand why it was written in a given way, saving the rest of engineers involved a good deal of communication overhead and time.
Other benefits
The first and main benefit of consistently adding JSDoc comments is that it helps you communicate about your code. The mere task of having to figure out the comment you will write on top of one method will help you think about it and clarify your method’s purpose. Moreover, we need to add the convenience of having the code explanation near the source code that is being commented. This way, developers won’t need to open a new browser tab to search for a piece of documentation that maybe doesn’t even exist. It also promotes a shared ownership of the code, reducing that ‘bus factor’ problem.
A typical problem of documentation is that, unless approached with methodology and care, it can easily get out of date. This problem can be mitigated by using documentation generators, because the comments that will produce our documentation sit right beside the source code you are modifying. The fact that we at Eventbrite rely on Code Reviews and Pull Requests to monitor the quality or our code means that they can also act as an enforcer of up-to-date comments. This synergy allows us to overcome the out-of-date factor of documentation and also enforce regular comments.
Lastly, commenting out your methods is not hard; it’s actually easy and fast! Regardless of your code editor, there are helper plugins for almost all tools out there: Sublime Text, Vim and PyCharm among others. You can also complete this task any time: while building containers in your dev environment, while running your acceptance test or while waiting for your CI tool to finish the build. Any two-minute slot of your day is a perfect time to add a small comment to your code that will improve a bit your codebase.
Conclusion
Using JSDoc comments makes documenting my methods an easy and manageable task. Sure, I could skip it, but it’s an easy way to fill my time productively and it has a huge pay-off for our engineering team. In other words, it doesn't take too much work to achieve a codebase that you can be proud of!
Resources
- Reference: Use JSDoc
- Plugins: Sublime Text, Vim, PyCharm
- Tips and Tricks: DocumentationJS, Common Pitfalls
Illustrations credit: Kwad-rat.