October 4, 2014

I’ve noticed when writing lots of small modules that the process of creating new modules and repositories can be a little tedious and error-prone. Automating the process makes things more efficient, produces consistent and clean repositories, and also forces me into the mindset of documenting and testing early on.

Here are some suggestions, tools and scripts that have improved my workflow. I’m going to presume OSX throughout this article, since I don’t use Windows.



example readme for a small module

terminal basics #

The best way to improve efficiency when working with npm modules is to get more familiar with terminal commands. You might already know cd and ls , but here’s a few other goodies:

tab key will auto-complete a path to the next folder; double-tap to list all paths that match the input

key will auto-complete a path to the next folder; double-tap to list all paths that match the input up/down arrow keys to repeat previous commands

arrow keys to repeat previous commands Ctrl + A and Ctrl + E to jump to the start/end of your current input

and to jump to the start/end of your current input touch README.md will create a new file called README.md if it doesn’t already exist

will create a new file called if it doesn’t already exist mkdir -p foobar creates a new folder called foobar if it doesn’t already exist

creates a new folder called if it doesn’t already exist open . opens the current folder in the Finder

opens the current folder in the Finder pbpaste > text.txt pastes the current clipboard contents into a new file called text.txt

There’s also some really handy utilities to improve efficiency in terminal. rupa’s z script is like a super-charged cd . It jumps to the given regex match, and remembers the most used patterns. So you could type z proj to jump to ~/Documents/projects .

Another one is opening your IDE at the current folder. Sublime users tend to use subl.

So a typical series might look like:

z proj mkdir foobar cd foobar subl .

And, of course, there are lots of tools like iTerm2 that act as replacements.

npm commands #

Once you’re comfortable with jumping around your file system and creating new files/folders, you can start speeding up your module creation process.

The easiest thing you can do is learn which npm commands will create and modify package.json for you:

# setup a bare-bones package.json npm init # can be used to bump version number and git commit npm version patch|minor|major # remember to use a flag when installing! npm install foobar --save npm install foobar --save-dev

With npm init you get a basic package.json , but not much more. Most modules will also want:

.gitignore so you aren’t committing node_modules etc

so you aren’t committing node_modules etc .npmignore so you aren’t pushing tests/bundles to npm

so you aren’t pushing tests/bundles to npm README.md formatted for discoverability/SEO

formatted for discoverability/SEO LICENSE.md so that companies can justify using your module to their legal teams

so that companies can justify using your module to their legal teams index.js or some aptly named entry point

or some aptly named entry point test.js to provide unit tests and give more confidence about the strength of the code

to provide unit tests and give more confidence about the strength of the code more detail in package.json (like GitHub repo) for better discoverability

This is where module-generator comes into play (originally forked from hughsk). You can, of course, fork it yourself to meet your needs, or find/write another module generator. The idea is to automate the tedious boilerplate for new modules.

To install:

npm install module-generator -g

After setting up your config, the process looks like this:

mkdir my-module cd my-module module-generator

This prompts for package details and sets up the essential stuff (readme, MIT license, gitignores, etc). Most importantly, it gives your modules a consistent “look and feel” and ensures they have all the details needed for discoverability and SEO.

It also produces a stability badge, which can be a useful hint to those depending on your module:

unit testing #

Unit testing your code is essential when you start working with small and re-usable modules; it will give other users more confidence in your code and also allow you to catch errors as you introduce new features and patches.

I use tape to support front- and back-end code. It’s much more light-weight and Unixy than jasmine/mocha/etc, requires less boilerplate, works in the browser, and integrates easily with other tools (like Git hooks).

Since I use it on almost all my modules, module-generator supports a --test or -t flag:

module-generator --test

This installs the latest verison of tape , saving it as a devDependency, creates an empty index.js , and generates basic test.js that looks like this:

var myFunkyModule = require('./') var test = require('tape').test test(/* description inserted here */, function(t) { t.end() })

Which allows you to start developing immediately with your tools of choice:

#run once node test #run continuously nodemon test #run in browser on localhost:9966 with LiveReload budo test --live

pushing to GitHub #

The next “tedious step” in the process of creating new modules is to push your module to GitHub. For this you can use the ghrepo tool, which pushes your folder to GitHub and pulls some details from your package.json .

#install tool globally first time around npm install ghrepo -g #push current folder to a new GitHub repo ghrepo -m "first commit"

more aliases #

Two other common tasks worth automating is a readme update, and publishing an npm patch.

You can add these to .bash_profile to get them when you next login to terminal. Shell aliases are another way of automating tasks you find yourself repeating a lot.

alias gitreadme='git add README.md; git commit -m "udpating readme"; git push' alias npmpatch='npm version patch;npm publish;git push;git push --tags'

further thoughts #

Hopefully we can continue to build more high-level tools that integrate all of these automations, improving efficiency and reducing human error.

To take the automation a step further, module tools could be integrated into an IDE, acting on a source file or even single function. Essentially it would “rip it out” of the application code, pushing it to its own npm folder and repo, and auto-document the readme based on code comments. Then, it would npm install the modularized version in place of where it was previously taken out.

134 Kudos