A Ruby Developer’s Guide to Creating Node Modules

In this guide, we’ll create a Node Module. Using all those Ruby terms you already know and love.

I’ve written many Ruby gems before. But I’ve never created the JavaScript equivalent. If this sounds like you as well, read on! I’ll share with you everything I’ve learned in the process of creating my first node module.

Terminology

Let’s start with some terminology. I’ll compare everything to the Ruby equivalent 😀.

  • npm is Node/JavaScript’s version of bundler. It allows you to install packages/manage dependencies. $ npm install package-name
  • a package is something you can install with npm. It can include one or more modules within it
  • package.json. Similar to a gemspec. Describes the functionality of your package and lists all the dependencies.
  • You can use $ npm install package-name --save to add a dependency to your package.json (Like adding a gem to your gemfile or gemspec).
  • packages are hosted on npmjs.com. Equivalent of RubyGems
  • a module is a library you can use within your app. Anything that you can require is a module. var cats = require(‘cats’);. You can have multiple modules within a package. Having a single module within a package is also okay (and recommended)

Modules Should Do One Thing™

The main difference I noticed between gems and modules is that modules are meant to do one thing™. This is why you see so many one-liner modules. The node community prefers to break functionality into many small modules rather than to group it all together in one. Ruby gems tend to have a wider scope than node modules.

Think of node modules as lego blocks. You don’t necessarily care about the details of how it’s made. All you need to know is how to use the lego blocks to build your lego castle. — Sindre Sorhus

If you’re interested more in the WHY behind this. I found this comment on GitHub to be very insightful.

Naming Conventions

npm & and the node community have naming conventions for packages (just like we do in Ruby land for gems).

Package names:

  • must be all-lower-case-separated-by-hyphens
  • must use URL friendly characters
  • have a max length is 214 characters

Easy right? Even more simple than Ruby. 🌟

For a full list of rules, see npm’s package for validating package names (wonderfully meta).

Is my name taken?
You can find out if your package name is taken from the console.

npm view i-want-this-name

If it returns a 404, then the name is available. 😀

If your name is taken and you still really want to use it. You can create a scope for your package name. Learn more here.

Getting Started

When you first start a Ruby gem, you typically run bundle gem to bootstrap the boiler plate code for your gem.

npm does not have anything quite like bundle gem. But it does have npm init for helping your create your package.json.

Reminder: package.json is similar to a Ruby gem’s gemspec. It describes the package and all of its dependencies.

If your new package is going to live on GitHub, I recommend creating the repository first. npm init will use your repo information to fill in some of the package.json for you.

Once your repository is created. Clone it and then run npm init.

git clone https://github.com/you/your-new-repo.git
cd your-new-repo
npm init

Writing the module

Remember that a module should only do one thing™. You should only need one file for your code. By convention it is named index.js.

At this point your directory structure should look like this.

index.js
package.json
README.md *
LICENSE *

*added when initializing your GitHub repo

If we wanted to create a module that adds two numbers together. It would look like this.

// index.js
module.exports = function(a, b) {
return a + b;
}

This allows us to use the module like this.

var add = require('./index.js');
add(1,2)
// => 3

Notice module.exports. It determines what is made available when we require the module. In this example, it exports the function definition for performing addition.

It’s possible to export more than one thing. But remember, keep it simple. 😀

Here’s an example with multiple exports.

// index.js
module.exports = {
hello: 'Hello, world',
  add(a,b) {
return a + b;
}
}

Now if we were to use this. It would work like this.

var myModule = require('./index.js');
myModule.hello
// => 'Hello, world'
myModule.add(1,2)
// => 3

If you’d like to learn more about exports, I recommend:

Trying it out in a REPL

As Ruby developers, we are generally very comfortable using REPL’s such as irb or pry. I personally rely heavily on pry during Ruby development.

Node has an equivalent REPL and it can be started by simply running $ node. Super useful when trying to understand how all the pieces fit together.

node REPL

Testing the module

There are a bunch of options for testing JavaScript. I picked mocha and chai because their syntax looks fairly similar to RSpec. This helped with reducing the learning curve.

First, you’ll need to install mocha and chai. Use the save-dev flag to add them as development dependencies in your package.json.

npm install mocha --save-dev
npm install chai --save-dev

Next, you’ll create the test file. test/index.js.

var expect = require(‘chai’).expect,
add = require(‘../index’);
describe(‘add’, function() {
it(‘adds two numbers together’, () => {
expect(add(1, 2)).to.eq(3);
});
});

To run the tests, from the root directory, run mocha test.

mocha test
add
✓ adds two numbers together
1 passing (9ms)

You can add this command to your package.json so that running npm test will work as well.

“scripts”: {
“test”: “mocha test”
},

Travis CI

Travis works just as well with Node modules as it does Ruby gems. Here is an example .travis.yml you can use to get yours setup.

language: node_js
node_js:
— “4.2”
— “4.1”
— “4.0”

Publishing the module

Before publishing, double check that the version is set correctly in your package.json. npm uses semver. If you’re not familiar, they have a helpful guide.

You’ll need to set your author information in npm. You can do this from the command line.

npm set init.author.name "Your Name"
npm set init.author.email "you@email.com"
npm set init.author.url "http://website.com"

npm adduser

Next, it’s recommended to tag the version in git before pushing. This makes the release easy to find on GitHub later.

git tag 0.1.0
git push origin master --tags

Finally, time to publish.

npm publish

Done! You’re now the author of a node module. 🌟

Learn More

I found these resources super useful when creating my first module.


Tweet me @mscccc 🌟.

You can 💥join my email list here💥. I send an email whenever I publish something new.

If you liked this post. Please hit recommend to share with your friends 😃.