Posted on Tuesday, June 23 2015 by Ionică Bizău
Few months ago I was introducing Blah–one of nicest tools I ever used in module/project development. It helped me a lot. Literally. More than 80% of my projects documentation was generated by this tool.
Recently I started building some new features, working on the 2.0.0 milestone of this project and finally, the 2.0.0 branch was merged. 97 commits, 34 files changed, and 1.659 lines changed (1,197 additions, 462 deletions). Cool, right? Let's see what's hiding behind these numbers.
The new big feature is templates. There are three levels of Blah templates:
~/.blah-templates
)You can read the pull request description if you want to find more technical details. Next, I will present a simple example how to use Blah 2.0.0 or how to automagically not waste your precious time for writing docs.
Thanks to npm
, the installation is easy:
$ npm i -g blah
If this command requires root access, make sure you configured NPM correctly. Using sudo npm i -g blah
is not a big issue, anyway.
When starting a project, I create the file structure which looks like below:
$ tree
.
├── example
│ └── index.js
├── lib
│ └── index.js
└── test
└── index.js
3 directories, 3 files
To create such a thing, do:
$ mkdir hello-blah && cd hello-blah
$ mkdir example lib test
$ touch example/index.js lib/index.js test/index.js
$ git init # if you want to have it as git repo
I always like to start by writing the example. In this case, let's make a library to display Hello World!
So, I do:
// Require the library file
var HelloBlah = require("../lib");
// Call the function exported by library
HelloBlah();
HelloBlah("Blah");
Obviously, node example/
will fail, because object is not a function
–in other words, we didn't export anything in the library file (lib/index.js
).
Now we have to write the library file:
/**
* HelloBlah
* Displays and returns a *Hello <world>!* message.
*
* @name HelloBlah
* @function
* @param {String} world The world you want to say *Hello* to (default: `"World"`).
* @return {String} The *Hello <world>!* message.
*/
function HelloBlah(world) {
world = world || "World";
var message = "Hello " + world + "!";
console.log(message);
return message;
}
module.exports = HelloBlah;
I used jsDoc comments that will help when generating documentation.
Now, since we exported the library function, our tiny example works fine:
$ node example/
Hello World!
Hello Blah!
There is one step before generating the documentation using Blah. Having a package.json
file (which is used to publish the library on npm registry) helps Blah:
{
"name": "blah-test",
"version": "1.0.0",
"description": "Testing the new version of blah.",
"main": "lib/index.js",
"directories": {
"example": "example",
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Ionică Bizău <[email protected]> (http://ionicabizau.net)",
"license": "MIT"
}
`
This can be generated using npm init
. As you probably noticed, I don't have time to write the tests for this library since it's not the main point of this article.
And now the most exciting part! You have a working library–small, cute, but not awesome enough without documentation. Blah does that for you.
Just run the following command and let the magic happen.
$ blah -c -g -r -l MIT -d lib/index.js
And now what? Blah generated the following files:
blah -c
or blah --contributing
)blah -g
or blah --gitignore
)blah -r
or blah --readme
)blah -l <license-name>
)And one more point: because it is smart enough, it put your information in the LICENSE file.
Most probably Blah used the default templates, in your case. The default templates are a set of defaults that (hopefully) everyone can agree on. Well, I don't. Since I maintain a bunch of projects, I want to have my own documentation format, adding some custom stuff to the default templates.
The Blah templates are written in EJS. Since it EJS lets us to run custom JavaScript code, it's very easy to write our custom stuff. For example I extended the package.json
file with the following fields:
{
"blah": {
"h_img": "http://example.com/heading-image",
"ex_img": "http://example.com/example-image"
}
}
I don't always use it, but sometimes I do. That's why I copied the default template into ~/.blah-templates/README.ejs
and added at the top of the file the following snippet:
<% if (_.pack.blah.h_img) { %>
![<%- _.pack.name %>](<%- _.pack.blah.h_img %>)
<% } %>
That means: if there is a heading image render it, otherwise do nothing.
If you want to see my customized templates, check out my dotfiles.
I published this example of using Blah here.
But sometimes these user-level templates are not enough–maybe you want to have some custom stuff inside of your project and not pollute your other projects with that.
Well, you need project-level templates. Blah does that for you. Run blah -i
to initialize the .blah
directory in your project. If you have user-level templates, they will be copied in the .blah
directory, otherwise the defaults will be copied.
Then, next time when you generate documentation with Blah, these templates will be used.
Finally, keep this in mind: generate documentation. It's easier, faster, better, cooler. Let Blah do that for you. Don't waste your time.
Like always, don't forget to check out the Blah project repository and open issues for anything (questions, bugs, features, discussions etc). Contributions are also welcome!
Happy Blahing!
Have feedback on this article? Let @IonicaBizau know on Twitter.
Have any questions? Feel free to ping me on Twitter.