How To Use npm to Build and Publish Node.js Packages on a Linux Server
Introduction
Node.js is a popular Javascript platform for server-side programming that allows you to build and run web apps quickly.
In this guide, we will talk about how to use npm
, a Node.js package management system. In a past guide, we discussed how to install Node.js on an Ubuntu 14.04 server. We have also discussed how to use npm as a package consumer by searching for and acquiring packages.
Now, we'll cover how to modify configuration settings, create and publish a package, and how to interact with the npm package repository. Let's jump right in.
Managing Configuration Settings
To control the behavior of npm, you can adjust the settings for the tool. There are quite a few ways built into npm to do this.
Listing the Current Configuration Settings
First, let's see what our current settings are. We can do this by typing:
npm config ls
; cli configs
registry = "https://registry.npmjs.org/"
user-agent = "npm/1.4.9 node/v0.11.13 linux x64"
; node bin location = /home/demouser/.nvm/v0.11.13/bin/node
; cwd = /home/demouser/projects/test_package
; HOME = /home/demouser
; 'npm config ls -l' to show all defaults.
This list of settings is pulled from a variety of different places, including the current operating environment. It is built when the command is run. You can test this by passing the -g
flag. It will suddenly show that the "global" option is set:
npm config ls -g
; cli configs
global = true
registry = "https://registry.npmjs.org/"
user-agent = "npm/1.4.9 node/v0.11.13 linux x64"
. . .
Right now, npm is not pulling any information from its configuration files because there are no configuration files that have been created yet. It is simply gathering information from its environment (current directory, etc.) and using the application defaults.
We aren't shown most of the defaults with this command though. To get more extensive information, we'll have to pass the -l
flag:
npm config ls -l
; cli configs
long = true
registry = "https://registry.npmjs.org/"
user-agent = "npm/1.4.9 node/v0.11.13 linux x64"
; default values
always-auth = false
bin-links = true
browser = null
ca = null
. . .
Getting and Setting Specific Values
As you can see, there are many key-value pairs of information. This is how we work with configuration values within npm. For instance, if we want to see the current value of the "editor" key, we can type:
npm config get editor
vi
If we want to change this value, we can easily do that by typing something like this:
npm config set editor vim
This will do two things. It will override the default value (vi) with our new value (vim), and it will also create our configuration file, since it is our first custom value.
Where is our configuration file written? Why don't we ask npm:
npm config get userconfig
/home/demouser/.npmrc
If we set values using the config set -g
syntax, they will be written to our globalconfig
file. We can find out where this is stored by typing:
npm config get globalconfig
/home/demouser/.nvm/v0.11.13/etc/npmrc
Your file location will differ depending on the method you used to install Node.js. Again, this file won't exist until you stray from the default values on the global level.
For the file that does exist, if you want to edit it with your editor, you can do that by typing:
npm config edit
This will not work if the file hasn't already been created yet (manually or by setting a non-default value within npm).
You can also set different configuration options for a specific command as you are calling it by using this syntax:
npm subcommand --key value
Other areas where values are pulled from are the package.json
file for the project itself and environmental variables.
Creating a Package with npm
We've learned a bit about how to use npm as a standard package manager to acquire and manage dependencies and packages that your application will need. However, you can also use npm to help you package and share your application or library.
One of the first things that npm helps with is generating a package.json file for your project. Before we begin, you should take a look at the help page for this so that you are familiar with the fields that you will be asked about:
npm help json
Once you are in your application directory, you can get started:
cd ~/projects/test_package
npm init
This will prompt you for information that it needs to build a package file for you. It will take some cues from the environment to populate default values. Your session might look something like this:
name: (test_package)
version: (0.0.0) 0.0.1
description: A test package
entry point: (index.js) index.js
test command: echo "test"
git repository: http://fake.git.repo.com
keywords: test
author: me
license: (ISC) GLP
About to write to /home/demouser/projects/test_package/package.json:
{
"name": "test_package",
"version": "0.0.1",
"description": "A test package",
"main": "index.js",
"dependencies": {
"express": "^4.2.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"test\""
},
"keywords": [
"test"
],
"author": "me",
"license": "GLP"
}
Is this ok? (yes) yes
If you have to install additional dependencies after you have generated your package.json
file, you should install them with the --save
flag, which will update the dependencies list in your package.json
file.
If your package requires very specific versions, you can use the shrinkwrap
subcommand. Usually, the package file sets your current packages as the minimum viable versions that are needed to build. With a shrinkwrap file, these versions are specific and locked down.
You can create this file with:
npm shrinkwrap
This will generate a file called npm-shrinkwrap.json
with very detailed package information for each dependency and in a recursive manner. If your application environment is delicate, this is an essential tool.
Interacting with the npm Website through npm
The npm project maintains a website of packages at npmjs.org. You can actually interact with this site through the npm command line tool. We've already discussed how you can search for packages, but there is more functionality as well.
First, if you haven't signed up with an account yet, you can do so from within the npm interface by typing:
npm adduser
You will be asked to select a username, a password, and an email address. These will be posted to the site, just as if you were registering through the web browser.
If you check your configuration, you should see your new account details:
npm config ls
. . .
; userconfig /home/demouser/.npmrc
editor = "vim"
email = "demouser@domain.com"
username = "demouser"
. . .
Publish your Package
When you have created a package that you wish to share with the greater Node.js community, the npm site is a great place to start.
Fortunately, npm comes with some helper functions that will get you started.
If you are in your package's directory, you can simply type:
npm publish
This will push your package onto the npm website. The success of this operation is dependent on your package having a unique name and version number. If you go there and search for your package, it should be listed just like any other Node.js package.
Tagging your Uploads
You can tag specific releases of your packages by using the tag
subcommand. These can be used in place of version numbers during installation and dependency specifications.
By default, npm will include a tag labeled "latest" to any package you publish. This just marks the most recent push. You can see this by typing:
npm config get tag
latest
This means that you can specifically request the latest version by typing things like:
npm install package@latest
If you want to add an additional tag to one of your package/version combinations, you can type something like:
npm tag package@version tag_name
This will let you now reference the version you tagged by the "tag_name" instead of the version number.
Altering Ownership of Packages
By default, when you publish a package, you will be given ownership of the package.
You can verify this by typing:
npm owner ls package_name
demouser <demouser@domain.com>
If you want to add additional people to the project, which will allow them to make modifications, you can issue a command like this:
npm owner add username
You can also do the reverse of this and remove rights from users like this:
npm owner rm username
At the time of this writing, all owners for a package have the same rights, so it is not possible to assign more fine-grained access control.
Removing and Deprecating Packages
Sometimes, there is an important change in your package that make it necessary to deprecate older versions. For example, maybe there was a security problem.
With npm, you can easily deprecate a version or a version range of your package by typing something like this:
npm deprecate package_name@"version_or_rangedeprecation_message_to_users"
The message that you choose to include will be shown as a warning to any user installing the package versions you've marked.
If you want to take your package down entirely, you can do that by unpublishing it. You should probably not do this if your package has been used by other people and npm encourages you to deprecate the package instead. You can also unpublish a specific version, but the same suggestion holds.
An important thing to note is that even if you unpublish a package and it is removed from the site, the name/version combinations it held cannot be reused ever. This is to ensure that people are not accidentally pulling the wrong packages.
The syntax for unpublishing your work is:
npm unpublish package_name@version
You can leave off the @version if you want to remove the entire package. In this case, you'll have to add the --force
flag so avoid accidental deletion of your entire project:
npm unpublish --force package_name
Conclusion
You should now have a fairly in-depth grasp of how to leverage the power of npm in your Node.js projects. The npm utility can be used to assist in most of the areas of project development, from building files and acquiring dependencies, to publishing packages and deploying into production.
2 Comments