npm tips and tricks

npmIn my previous post I showed you how easily you can create a simple webserver using Node.js. In this post I want to show you how to make more advanced usage of node package manager.

npm init

Using node package manager you can get an even quicker start of your project by using the npm init command. So let’s get started by opening a command prompt (on windows open the Node.js command prompt). Then create a new folder and navigate into this newly created folder. In the folder execute following command and answer the questions or press enter for the defaults.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Your environment has been set up for using Node.js 0.10.17 (x64) and npm.
Press any key to continue . . .
C:\Users\Marco> mkdir NodeJsPackageExample
C:\Users\Marco> cd NodeJsPackageExample
C:\Users\Marco\NodeJsPackageExample> 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: (NodeJsPackageExample) node-js-package-example
version: (0.0.0) 0.0.1
description: Total package awesomeness
entry point: (index.js)
test command:
git repository:
keywords: package, awesomeness
author: Marco Franssen
license: (BSD-2-Clause) MIT
About to write to C:\Users\Marco\NodeJsPackageExample\package.json:
{
"name": "node-js-package-example",
"version": "0.0.1",
"description": "Total package awesomeness",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"package",
"awesomeness"
],
"author": "Marco Franssen",
"license": "MIT"
}
Is this ok? (yes) yes

After answering the questions the result should be something like above. As you can see I have changed the default name. By default node package manager uses the folder name. Play around yourself to get the desired result. You can also change the package.json after it is created.

Why do we need this package.json file?

The answer is simple… When we put our code in source control (GIT, SVN, TFS) we don’t want to commit all our third party packages. We want to leave them out of the source control. Another reason is we also don’t want to ship all dependencies as part of our own package when we release our package to the npm registry. All team members or users of your package who checkout your code or download your package are simply missing all the dependency packages and this is where the packages.json comes in. After downloading the package, they simply execute npm install. This will download all dependencies etc. based on your package.json file.

npm install

So let’s continue with some more npm tips and tricks. The second thing you may already have seen by executing npm init is the npm install –save command. Npm install –save will install your package and saves it in the package.json file. Skipping the –save option will simply not add the package to your package.json file. Let’s start by adding the express package, which we also used in previous post.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
C:\Users\Marco\NodeJsPackageExample> npm install --save express
npm WARN package.json node-js-package-example@0.0.1 No repository field.
npm WARN package.json node-js-package-example@0.0.1 No README data
npm http GET https://registry.npmjs.org/express
...
...
left for brevity
...
...
express@3.4.6 node_modules\express
├── methods@0.1.0
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── fresh@0.2.0
├── debug@0.7.4
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── mkdirp@0.3.5
├── commander@1.3.2 (keypress@0.1.0)
├── send@0.1.4 (mime@1.2.11)
└── connect@2.11.2 (uid2@0.0.3, pause@0.0.1, qs@0.6.5, raw-body@1.1.2, bytes@0.2
.1, negotiator@0.3.0, multiparty@2.2.0)

As you can see the package express is installed including all dependencies. In our package.json we can see the dependency added.

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"name": "node-js-package-example",
"version": "0.0.1",
"description": "Total package awesomeness",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"package",
"awesomeness"
],
"author": "Marco Franssen",
"license": "MIT",
"dependencies": {
"express": "~3.4.6"
}
}

Now you know how to install a package and save it to the package.json. To uninstall a package and remove it from your package file just execute the npm uninstall –save command.

repository and readme.md

When you just like me skipped the repository during npm init, you just have seen two warnings. Let’s solve both by adding a repository in the package.json file and a Readme.md file in the root of our package.

1
2
3
4
"repository": {
"type": "git",
"url": "https://github.com/marcofranssen/NodeJsPackageExample.git"
}

Do not forget to add some contents in your Readme.md file, otherwise npm won’t be satisfied. A title and a short description should be ok.

npm install dev package

When deploying a package on a server you don’t want your development packages published on the server. An example of such a development package is grunt. So we want to save such package in a different way so our colleague developers can install the development packages, but our production server can skip them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
`C:\Users\Marco\NodeJsPackageExample> npm install --save-dev grunt
npm http GET https://registry.npmjs.org/grunt
...
...
left for brevity
...
...
grunt@0.4.2 node_modules\grunt
├── dateformat@1.0.2-1.2.3
├── which@1.0.5
├── eventemitter2@0.4.13
├── getobject@0.1.0
├── colors@0.6.2
├── hooker@0.2.3
├── async@0.1.22
├── exit@0.1.2
├── coffee-script@1.3.3
├── underscore.string@2.2.1
├── iconv-lite@0.2.11
├── lodash@0.9.2
├── findup-sync@0.1.2 (lodash@1.0.1)
├── nopt@1.0.10 (abbrev@1.0.4)
├── rimraf@2.0.3 (graceful-fs@1.1.14)
├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
├── minimatch@0.2.12 (sigmund@1.0.0, lru-cache@2.5.0)
└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)`

As you can see all dependencies of grunt are automatically installed and a new property is added to your packages.json file.

1
2
3
"devDependencies": {
"grunt": "~0.4.2"
}

With grunt installed you can speed up your development even more by automating a lot of tasks. These are tasks like running tests, minifying, compiling Less/Sass etc. I would like to challenge you and share your grunt scripts with me and the rest of the developer community by posting a reaction on this post. For more help on grunt visit http://gruntjs.com/.

private package

If your package is not intended to be shared or reused on the _npm registry _make sure to protect yourself by adding the following setting in your package.json.

"private": true

This will prevent you from accidentally publish your package to the npm registry.

npm update

While working on your awesome package you probably want to update your dependencies before you publish your package so you are running the latest code of all packages.

To check if there are any package updates available you can run the following command.

1
2
3
4
5
6
C:\Users\Marco\NodeJsPackageExample> npm outdated
npm http GET https://registry.npmjs.org/express
npm http 200 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/express/-/express-3.4.7.tgz
npm http 200 https://registry.npmjs.org/express/-/express-3.4.7.tgz
express@3.4.7 node_modules\express current=3.4.6`

As you can see there is a new release of the express package. Since it is a patch release (increment of 3th number) I decide to update this package.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
C:\Users\Marco\NodeJsPackageExample> npm update --save express
npm http GET https://registry.npmjs.org/express
npm http 304 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/express/3.4.7
...
...
left for brevity
...
...
express@3.4.7 node_modules\express
├── methods@0.1.0
├── merge-descriptors@0.0.1
├── fresh@0.2.0
├── buffer-crc32@0.2.1
├── debug@0.7.4
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── cookie@0.1.0
├── mkdirp@0.3.5
├── commander@1.3.2 (keypress@0.1.0)
├── send@0.1.4 (mime@1.2.11)
└── connect@2.12.0 (uid2@0.0.3, pause@0.0.1, qs@0.6.6, bytes@0.2.1, batch@0.5.0,
raw-body@1.1.2, negotiator@0.3.0, multiparty@2.2.0)

Node package manager uses semantic versioning and it is up to the package creator/publisher to follow these guidelines. So always double check what has changed and see if your package still works after upgrading the dependencies. Usually you should be safe when installing patch releases. Be more carefull when you upgrade minor or major releases. More information about versioning can be found here. Make sure your package satisfies these guidelines when publishing new and updated packages since this will help other developers during the update process.

npm publish

Creating a package is one thing, but the second thing is you probably want to share it with the community. Sharing a package with the community is pretty straight forward.

First of all we need to set our npm author info if you haven’t already done so. This can be done by executing following commands.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
C:\Users\Marco\NodeJsPackageExample> npm set init.author.name "Marco Franssen"
C:\Users\Marco\NodeJsPackageExample> npm set init.author.email "marco.franssen@gmail.com"
C:\Users\Marco\NodeJsPackageExample> npm set init.author.url "http://marcofranssen.nl"
C:\Users\Marco\NodeJsPackageExample> npm adduser
Username: marcofranssen
marcofranssen
Password:
Password:
Email: marco.franssen@gmail.com
npm http PUT https://registry.npmjs.org/-/user/org.couchdb.user:marcofranssen
npm http 409 https://registry.npmjs.org/-/user/org.couchdb.user:marcofranssen
...
...
npm http PUT https://registry.npmjs.org/-/user/org.couchdb.user:marcofranssen/-r
ev/4-84c649f53b8faf80bc10b02a190bcb64
npm http 201 https://registry.npmjs.org/-/user/org.couchdb.user:marcofranssen/-r
ev/4-84c649f53b8faf80bc10b02a190bcb64

Now your user account is created and you’re able to publish packages to the npm registry.

The last thing waiting for us is to publish the actual package. Which can be done using following command.

1
C:\Users\Marco\NodeJsPackageExample> npm publish ./

Since I have put the private flag on true in my package.json.

"private": true

I got following error:

1
2
npm ERR! Error: This package has been marked as private
npm ERR! Remove the 'private' field from the package.json to publish it.

So when I remove this from my package.json and execute publish command again it should succeed and your package will be listed in the npm registry.

1
2
3
4
5
6
7
8
C:\Users\Marco\NodeJsPackageExample> npm publish ./
npm http PUT https://registry.npmjs.org/node-js-package-example
npm http 201 https://registry.npmjs.org/node-js-package-example
...
...
...
npm http 201 https://registry.npmjs.org/node-js-package-example/0.0.1/-tag/latest
+ node-js-package-example@0.0.1

unpublish

Since the package I just published won’t be of any value I removed it using following command.

1
2
3
4
5
6
7
8
C:\Users\Marco\NodeJsPackageExample> npm unpublish ./ --force
npm WARN using --force I sure hope you know what you are doing.
...
...
npm http DELETE https://registry.npmjs.org/node-js-package-example/-rev/3-366120337d
9f89cd2ca7fc0c4489281d
...
...

I hope this article showed you some of the nice stuff you can do to quickly build your first node package and get it published in the npm registry. Using npm you should get better control over your dependencies and it should become easier for you and your team to keep track on those dependencies.

Also have a look at https://npmjs.org/doc/developers.html to learn even more about the Node Package Manager.

Thanks for reading.

Share