Skip to content

Instantly share code, notes, and snippets.

@acataluddi
Forked from tmpvar/my-first-module.md
Last active April 8, 2020 17:37
Show Gist options
  • Save acataluddi/718f51b2122e86bbad02b7c6d839d7f0 to your computer and use it in GitHub Desktop.
Save acataluddi/718f51b2122e86bbad02b7c6d839d7f0 to your computer and use it in GitHub Desktop.
how to create your very first node.js module and publish it to the npm registry

Building an NPM package

This is pretty simple, lets dive in!

Choose a name

Find a name that isn't taken and clearly describes what your module is doing

$ npm view your-first-node-module
npm http GET https://registry.npmjs.org/your-first-node-module
npm http 404 https://registry.npmjs.org/your-first-node-module
npm ERR! 404 'your-first-node-module' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it
npm ERR! 404 
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, or http url, or git url.

npm ERR! System Darwin 13.0.0
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "view" "your-first-node-module"
npm ERR! cwd /Users/tmpvar/work/tmp
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.24
npm ERR! code E404
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/tmpvar/work/tmp/npm-debug.log
npm ERR! not ok code 0

Woohoo, that name is not taken lets take it.

Project initialization

It's probably best if you create a github repo before initializing your project

git clone [email protected]:user/your-first-node-module.git
cd your-first-node-module

Ok, now we are ready to initialize package.json which will let npm know what the name of your module is as well as what dependencies it uses


$ npm init .
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (your-first-node-module) 
version: (0.0.0) 
description: very first module
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: Elijah Insua <[email protected]> (http://tmpvar.com)
license: (ISC) MIT
About to write to /Users/tmpvar/work/tmp/your-first-node-module/package.json:

{
  "name": "your-first-node-module",
  "version": "0.0.0",
  "description": "very first module",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Elijah Insua <[email protected]> (http://tmpvar.com)",
  "license": "MIT"
}


Is this ok? (yes) 

npm init . will ask you a couple of questions. Once you've finished filling them out you can take a peek at the package.json file it generated to see what it actually did.

$ cat package.json
{
  "name": "your-first-node-module",
  "version": "0.0.0",
  "description": "very first module",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Elijah Insua <[email protected]> (http://tmpvar.com)",
  "license": "MIT"
}

You can also hand edit this file if you need to.

Code time

Some words of advice

  Modules should do one thing.  If you have a `lib` directory with a grab bag of utilities and
  other _stuff_ in there, you should break those out into their own modules.
  
  Modules should be easy to digest and focused on the task they were created to perform
  

The hello world module

So lets create a new file index.js and make it compute the area of a rectangle. Why? because it's a really easy demo!

index.js

module.exports = function(width, height) {
  return width * height;
};

the filename I chose was index.js, but you could name it whatever you want. If you change it you should update package.json's main property to match.

What is that module.exports thing?

When node loads your module it's actually wrapping it in a function that looks sort of like:

function(__dirname, __filename, module, exports) {
// ...
}

Where __dirname and __filename are the current directory and filename of the file being loaded.

module.exports provides a way for modules to expose functionality. Lets take a look at how this would work with our example..

exports is actually module.exports and can be safely ignored. It's legacy, man!

node repl

$ node
> var area = require('./index.js');
undefined
> area(2,4)
8
>
(^C again to quit)
> 

(hint: press control+c 2 times to exit the repl)

Because we set module.exports to a function, it is the only thing exported. We can call it directly!

publish time

if you are a new user

npm adduser <your username>

Follow the steps and you'll have an account that let's you publish to the npm registry!

lets get this module out into the world!

Ok, we've made a module! Lets push it out so anyone can use it

$ npm version 1.0.0
v1.0.0
$ git add package.json test.js
$ git commit -m "release 1.0.0"
$ git tag 1.0.0
$ git push && git push --tags
$ npm publish

And that's it!

note: the git tag of that operation is not required, but can be extremely useful if people report bugs against a specific version

homework

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment