As a software developer, I can tell you that documentation plays an important role in my work. But why are so many developers lacking proper documentation? Do they have the appropriate documentation tools? Are there any helpful apps that could help in generating proper documentation?
Regardless of your technical skill level or the type of documentation you’re creating, there is a documentation generator for it. You can decide between a simple one-click setup and simpler content creation. There are websites that cater to different needs of businesses. Some people need a bigger picture, others a TOC in order to fully understand the product or service you’re offering. This is why it’s best to do some research before choosing the best documentation generator for your business.
More and more people are realizing the importance of writing clean, understandable and well-documented code. Adequate documentation for web applications can make the life of everyone involved easier, as it makes it easier to understand the code at hand and to modify it.
Suppose you write a block of code for a software today, or a couple of functions to achieve a given functionality. At the moment of writing the code, everything is clear in your mind, and you can understand what every piece and every line does in your code. However, months later, you may look at your code and wonder if you were the one who wrote the code, especially if the code is not documented.
Why you need JSDocs
As we all know, writing code documentation can be very tedious. Therefore, we need something to cut time. The main idea behind JSDocs is to generate documentation for functions, classes, and methods.
The benefit of using JSDocs for your code is how easy it is to export to HTML. Moreover, it integrates well with IDE’s and code editors such as VS Code which has an extension for it.
Goal
By the end of this tutorial, the reader should have learned how to initialize JSDocs in a JavaScript program and use it in a real-life programming scenario. We will write code snippets that are documented using JSDocs to demonstrate this concept.
Insight
If you take a look at the function below, it is easy to tell what the function does as it speaks for itself.
From the function name to its parameters, we can tell that this function calculates the area of a rectangle by taking the length and width as parameters.
function calculateArea(length, width, area) {
area = length * width;
return area;
}
If we change the function and parameter names, this function could mean something else. We can use the JSDocs documentation API to help us describe the function better than it speaks for itself.
You add a line of comment starting with an asterisk *
before the function name to document it:
/**
* function to calculate the area of a rectangle
*/
function calculateArea(length, width, area){
area = length * width;
return area;
}}
JSDocs Annotations
Writing the function name alone is not enough. With JSDocs annotation, we can make things more interesting by documenting parameters as well.
For each parameter, we take note of its type and the description of what it does in the code. The syntax for a function parameter is shown below.
/**
*
* @param {parameter type} parameter name - parameter description
*
*/
- Type: parameter type may be a
string
,integer
,array
,floating-point
, etc. - Name: every parameter must have a name for referencing purposes in the code and when the function is called.
- Description: an explanation of what the parameter is about.
Project Setup
We have had a glimpse of how to use JSDocs documentation API. To understand more, create a folder and name it project
.
Head over to your terminal and run the following commands.
npm init -y
npm i- dev jsdocs
We need a config file to use JSDocs. In the root folder of the application, create a file named jsodc.json
and paste the following snippet.
{
"source": {
"include": ["source"],
"includePattern": ".js$",
"excludePattern": "(node_modules/|docs)"
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": true,
"monospaceLinks": true
},
"opts": {
"recurse": true,
"destination": "./documentation/"
}
}
In the root folder, create a new folder named source
and add a new file named index.js
inside it. Here is where we are going to write the code whose documentation is to be generated.
Creating the Startup Script
Add the snippets below in the Script Object in the package.json
file:
"doc": "jsdoc -c jsdoc.json"
Now run the command npm run doc
after which you’ll see a folder called documentation
in your root folder.
At this time, your folder structure should be as shown below:
|-- jsdocs.json
|-- package-lock.json
|-- package.json
|-- documentation
| |-- index.html
| |-- fonts
| |-- scripts
| |-- style
|-- source
|-- index.js
If you open your index.html
file in the documentation
folder, you should see the auto generated page where your documentation will go.
How to document your code #
There’s a standard approach to JS documentation known as JSDoc. It follows a standard format.
/**
* [someFunction description]
* @param {[type]} arg1 [description]
* @param {[type]} arg2 [description]
* @return {[type]} [description]
*/
var someFunction = function (arg1, arg2) {
// Do something...
};
Here’s an example with an actual function, to help make it stick.
/**
* Add two numbers together
* @param {Number} num1 The first number
* @param {Number} num2 The second number
* @return {Number} The total of the two numbers
*/
var addTwoNumbers = function (num1, num2) {
return num1 + num2;
};
In addition to @param
and @return
, there are useful tags like @todo
, @deprecated
, @license
, and so on.
The structure follows a convention used in other languages like PHP. I like it so much, I use it in CSS, too (something Tim Kadlec tried to get going that never really took off).
JSDoc can also be used to automatically generate README
style docs, but I prefer to hand-write that kind of documentation. More on that in a minute.
Adding additional info inside the function #
I use JSDoc for the main function overview, and sometimes that’s enough. Our addTwoNumbers()
function above, for example, is fully described by the JSDoc heading.
But for slightly bigger functions, it’s useful to add one-line (or sometimes multi-line) comments within to describe what’s happening.
This may seem overdone. I’ve had some more pretentious engineers tell me I over-document.
But future me always thanks past me for doing this when I come back to a project I haven’t touched in a while. I’m never sitting there wondering what a line of code does or why I wrote it.
Try working on someone else’s “self-documented code” and tell me you wouldn’t rather have it over-documented than under-documented.
Here’s a sample function. Can you tell me what each line does?
/**
* Toggle visibility of a content tab
* @param {String} selector Selector for the element
* @param {Node} toggle The element that triggered the tab
*/
var toggleVisibility = function (selector, toggle) {
if (!selector) return;
var elem = document.querySelector(selector);
if (!elem) return;
elem.classList.add('active');
if (toggle) {
toggle.classList.add('active');
}
elem.focus()
if (document.activeElement.matches(selector)) return;
elem.setAttribute('tabindex', '-1');
elem.focus();
};
Maybe you could. Did it take a little while?
Now, here’s an example with proper in-context documentation.
/**
* Toggle visibility of a content tab
* @param {String} selector Selector for the element
* @param {Node} toggle The element that triggered the tab
*/
var toggleVisibility = function (selector, toggle) {
// If there's no selector, bail
if (!selector) return;
// Get the tab to show
var elem = document.querySelector(selector);
if (!elem) return;
// Show the element
elem.classList.add('active');
// If a toggle element was provided, add an .active class for styling
if (toggle) {
toggle.classList.add('active');
}
// Bring the newly visible element into focus
elem.focus()
// If elem.focus() didn't work, add tabindex="-1" and try again
// (elements that aren't focusable by default need a tabindex)
if (document.activeElement.matches(selector)) return;
elem.setAttribute('tabindex', '-1');
elem.focus();
};
TypeDoc
Documentation generator for TypeScript projects.
Documentation
For more detailed documentation, the changelog, and TypeDoc documentation rendered with TypeDoc, see https://typedoc.org.
Installation
TypeDoc runs on Node.js and is available as a NPM package.
npm install typedoc --save-dev
Usage
To generate documentation TypeDoc needs to know your project entry point, and TypeScript compiler options. It will automatically try to find your tsconfig.json
file, so you can just specify the entry point of your library:
typedoc src/index.ts
If you have multiple entry points, specify each of them.
typedoc package1/index.ts package2/index.ts
If you specify a directory, TypeDoc will use the entryPointStrategy
option to determine how to resolve it. By default, TypeDoc will search for a file called index
under the directory.
Docsify
Docsify is being showcased as A magical documentation site generator. and well… it does its job quite nicely. What’s important is that it renders your documentation on the fly, which means that you don’t have to parse your MD to HTML – just put your files, where they should be and you’re good to go! Also, Docsify has a great number of plugins and some themes to choose from. It’s also well-documented (like a documentation generator should be). I might be a little biased as my own project’s documentation is using this tool. The only problems with it (at least for me) is that’s its compatibility with IE10+ (as written on its page) is not really good (but they’re working on it) and it lacks support for relative links.
Docute
Docute is a similar tool to Docsify with a cute name. The newest version (v4) feels a bit less documented than the previous one but it also simplifies things a little bit. Generated docs look minimalistic, simple and elegant. The theme can be customized using CSS variables. Docute doesn’t have so robust plugin system as Docsify, but it has its own advantages. It’s built on Vue.js, which result in slightly bigger bundle size than that of Docsify but also allows for a lot of extendability. For example, in your MD files, you can use some of the built-in Vue components or even your own ones.
Slate
Slate is probably the leader when it comes to documenting your projects and its stars on GitHub (~25,000). Its docs feature clean and readable syntax with the everything-on-one-page feature. It comes with pretty solid GH wiki documentation. It allows for vast theming but you’ll have to do digging yourself as the documentation doesn’t provide much info. Sadly, it isn’t much extendable, but quite feature-packed. It seems like especially good option for those who need nice docs for REST API. Keep in mind that Slate generates static HTML files instead of doing this at runtime.
Monorepos / Workspaces
If your codebase is comprised of one or more npm packages, you can pass the paths to these packages and TypeDoc will attempt to determine entry points based on package.json
‘s main
property (with default value index.js
) and if it wasn’t found, based on types
property. If any of the packages given are the root of an npm Workspace or a Yarn Workspace TypeDoc will find all the workspaces
defined in the package.json
. In order to find your entry points, TypeDoc requires either that you turn on sourcemaps so that it can discover the original TS file, or that you specify "typedocMain": "src/index.ts"
to explicitly state where the package entry point is. Supports wildcard paths in the same fashion as those found in npm or Yarn workspaces.
Single npm module
typedoc --entryPointStrategy packages .
Monorepo with npm/Yarn workspace at the root
typedoc --entryPointStrategy packages .
Monorepo with manually specified sub-packages to document
This can be useful if you do not want all your workspaces to be processed. Accepts the same paths as would go in the package.json
‘s workspaces
# Note the single quotes prevent shell wildcard expansion, allowing typedoc to do the expansion typedoc --entryPointStrategy packages a-package 'some-more-packages/*' 'some-other-packages/*'
Arguments
For a complete list of the command line arguments run typedoc --help
or visit our website.
--out <path/to/documentation/>
Specifies the location the documentation should be written to. Defaults to./docs
--json <path/to/output.json>
Specifies the location and file name a json file describing the project is written to. When specified no documentation will be generated.--options
Specify a json option file that should be loaded. If not specified TypeDoc will look for ‘typedoc.json’ in the current directory.--tsconfig <path/to/tsconfig.json>
Specify a typescript config file that should be loaded. If not specified TypeDoc will look for ‘tsconfig.json’ in the current directory.
Source file handling
--exclude <pattern>
Exclude files by the given pattern when a path is provided as source. Supports standard minimatch patterns.--excludeNotDocumented
Only document items which have a doc comment. This option is useful, if you want to document only small part of your symbols and do not show the remaining ones in the documentation.
Theming
--theme <default|plugin defined theme>
Specify the theme that should be used.--name <Documentation title>
Set the name of the project that will be used in the header of the template.--readme <path/to/readme|none>
Path to the readme file that should be displayed on the index page. Passnone
to disable the index page and start the documentation on the globals page.
Miscellaneous
--listInvalidSymbolLinks
Display the list of links that don’t point to actual code symbols.--version
Display the version number of TypeDoc.--help
Display all TypeDoc options.
Conclusion
A lot can be said about building great documentation for newly written JavaScript. The value it adds to your project cannot be understated. However, people often overlook best documentation generators for javascript, which leads to the false assumption that JavaScript doesn’t have any formal documentation standards.
Documentation generators in Javascript are an essential part of most projects since they reduce the work required to produce descriptive and detailed documentation for your code. As a developer, you want to save as much time as possible so that you can focus on other tasks in your project. Apart from having in-depth knowledge about the specific project, writing the documentation is one of those tasks that consumes a lot of time. Adding to this, you also need to ensure that the descriptions and details you provide are accurate and relevant, which is where the documentation generator comes in handy.