|
|
@@ -0,0 +1,196 @@ |
|
|
# 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 [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. |
|
|
|
|
|
```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 <[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__ |
|
|
```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 <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 |
|
|
|
|
|
* add tests to your module |
|
|
* read about [semver](http://semver.org/) |