# building your first node module 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 ```bash $ 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 ```bash git clone git@github.com: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 --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 (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 (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. ```bash $ 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 (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__ ```javascript 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: ```javascript 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__ ```bash $ 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 ``` 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 * add tests to your module * read about [semver](http://semver.org/) * add some dependencies to your project [managing-dependencies.md](https://gist.github.com/NeoTech/8746517)