10 Cool Things You Probably Didn’t Realize npm Could Do
Some of this is no longer 100% accurate, which shouldn’t be very surprising, since it was written 7 months ago, and npm had a major version update since then.
Check out the node blog for some of the 1.0 changes.
npm is the node package manager. Once upon a time, I would have said “a” node package manager, and the humbler part of me would like to pretend that that’s still the case, but SCREW THAT HUMBLER SIDE, I’m feeling egotistical and braggy today, so today it’s THE node package manager.
Also, I’m writing a “head -n 10” blog post, so it’s basically a license to be a complete ass.
Yeah, it’s that kinda day. I think tomorrow, Imma eat a turkey. So there.
You probably know that npm can install stuff, publish stuff, remove stuff, and that it makes dependencies magically work. You may even know that it runs without being burdened by unnecessary semicolons.
If you’re a node veteran, you may even already know about some of these lesser-known features. But I’m hoping that at least one of them is a bit surprising, even for old timers and core node devs.
1: Handle multiple versions of the same thing at the same time
One of the reasons I wrote npm is that package managers put you in dependency hell, and I simply can’t abide that.
npm keeps all its installed packages organized in name/version folders, and versions all the public stuff. Then, one of them is “active” at any given time in the global space. (That’s what you’ll see if you install multiple versions of “foo” and then drop into the repl and do require(“foo”).)
But here’s where it gets cool: Let’s say that you installed email@example.com and firstname.lastname@example.org. Now, you have email@example.com that depends on firstname.lastname@example.org, and email@example.com that depends on firstname.lastname@example.org, and email@example.com that depends on bar and baz.
Here’s a diagram:
firstname.lastname@example.org | +— email@example.com | | | `— firstname.lastname@example.org \ | \ `— email@example.com > Conflict? | / `— firstname.lastname@example.org /
In most package manager systems, quux would simply never be installable. It needs two packages that can’t coexist because they have competing dependencies. Or, you’d have to name things stupidly, and bar and baz would have tobe aware of one another.
npm handles that all for you. Try it. It works.
It’s MAGIC. (Also, it’s the commonjs module system’s built in separation of scope that doesn’t require that the path be a single consistent thing.)
2: Be gone at runtime
npm doesn’t load your modules. It installs them. Then you can even do npm rm npm and it’ll remove itself. All the modules you installed? Yeah, they still work.
It does this by setting up things in the proper places so that node’s very simple module loader can find them when it needs them.
Most package managers are sort of hybrid loader/installer things. npm is first and foremost a dependency manager. It puts things in place, and then ducks out of the way so that it’s not all in your face telling you how to write your programs.
3: Structure your program any way you want
…provided, of course, you describe that structure in a package.json file.
That is, you can put all your node modules in a folder called “src” or “lib” or “path/to/my/awesome/modules”. npm doesn’t care. In fact, it doesn’t even need to be a node program. If you can describe the package in a package.json file, you can install literally anything. I’m waiting for people to figure this out, and see something awful and hideous like npm install vim.
A lot of people have objected to this feature. They called me crazy and said that we need to form a committee and decide on a set of conventions. Some even went so far as to pound fists on tables, and declare that madness will surely result from my freewheeling insanity!
Read through npm help json to learn what you can put in your package.json file.
4: Start a package.json file for you
If you run npm init in a folder, it’ll ask you a few questions, and then write out a package.json file.
The init command is pretty new, and doesn’t do much. But sometimes all you need is a little nudge to get started.
5: Verify sha1 hashes of packages
As of version 0.2.9, sha hashes get generated for all packages as they get published, and then are verified after being downloaded.
Checksumming is one of those things where everyone feels a little safer knowing it’s there, but no one usually pays much attention to it. When it works, it’s silent, and that’s great.
The good news is that, now, if there’s some kind of error downloading something, or if something gets corrupted in transit in any other way, then npm will stubbornly refuse to proceed.
(You have to compile node with openssl crypto support for this to work.)
6: Shut The Hell Up
Sometimes you just need to show your packager who’s boss. “Shutting up” is a feature. By setting the loglevel config, you can make npm anywhere from completely silent to ludicrously noisy. The levels are: silent, win, error, warn, info, verbose, and silly.
- silent: completely silent. Zero logging output.
- win: Just the “npm ok” or “npm not ok” message at the end.
- error: When something unexpected and bad happens.
- warn: When something odd or potentially dangerous is happening.
- info: Helpful information so you can track what’s happening.
- verbose: Even more. Perhaps just a wee bit obnoxious, even.
- silly: Completely fuckin crazy, man. Dump everything. Whole objects, you name it, whatever.
Like any configuration option, you can set the loglevel in a few ways. To set it for just one command just add —loglevel silent to the command. This is particularly handy if something breaks, and you want to provide a bit more debugging output with —loglevel verbose.
To set it for your user account, you can do npm config set loglevel win.
To set it globally for all users on the machine, you can do npm config set loglevel info —global.
You can also set it in the environment if that floats your boat. Any config option can be set by the npm_config_<blerg> environ, so doing export npm_config_loglevel=verbose will affect all subsequent npm commands.
Oh, and if those npm config set and npm config get commands get tedious, you can just do npm c edit to open up the config in your favorite editor.
See npm help config for more info.
7: Abbreviate commands
If you’re anything like me, then you drink a lot of coffee, hate extra typing, and are awesome. But mostly the typing. Let’s focus on that.
Is “install” just too long for you? Try npm inst connect. Bam. Done.
Anything that is unambiguous will work just as well. I don’t have this logic implemented for arguments and package names, but that’s on the roadmap. It uses the abbrev program, and you can use it in your programs, too. npm i abbrev to get it.
The most common commands even have super short shorthands, because I love you.
- i: install
- r, rm: uninstall
- ln: link
- ls: list
- bn: bundle
- up: update
- c: config
If you think it stops there, you’re wrong. So wrong. Go sit in the corner.
In the npm source folder, there’s a file called npm-completion.sh. Source that bad boy in your bashrc or whatever, and you’ve got tab completion.
Tab completion! The penultimate feature of any unix program, second only to tab completion that works and is helpful!
This is where you come in. Check out what it’s doing. Dig into the code. Make it better. Right now it can just tab-complete npm commands, not package names or other useful things. But if you hack away on the lib/completion.js file, you can make it awesomer.
8: Get help on anything
npm has a ton of documentation. In fact, the biggest documentation problem at the moment in npm is that there’s too much of it, and it’s probably impossible for any non-robot to read all if it in a reasonable amount of time.
In case you’re not a robot, here’s how you can get the most out of the docs:
- run npm without any arguments. This’ll show you what you can do. It lists out the commands and the help topics.
- run npm command -h to quickly view the arguments that command expects. This is handy when you forget how to do something that you knew how to do, and you just need to remember how you did it.
- run npm help <topic> to get more detailed manpage-style documentation. For general info about npm itself, you can run npm help npm. This page has a few pointers based on your use cases. Check it out.
9: View specific fields on published packages
The npm view command was pretty lame for a while. Basically it just fetched data from the registry and then dumped it to the terminal. But now, it’s so much more.
Specify a package name (in the form of name@version or name@latest or name or even name@”>=1.2.3" for ranges), and optionally one or more fields, and it’ll pull just those fields out and show them to you.
It operates smartly on arrays, and parses out the url and email fields from contributors and author names. So, if you do this:
npm view npm contributors.name
then you’ll get a list of all the contributor names in npm. If you just do:
npm view npm contributors
then you’ll see the list of contributors in the “name (url) <email>” format.
10: Bump your package version FOR YOU OMG HOLY CRAP WHAT!?
Yeah. That’s right.
It’ll even commit the change, and tag it for you, if you do it in a git repo. Just run:
npm version 1.2.3
It’ll open up your package.json file, change the version to 1.2.3, git add it, git commit it, and git tag v1.2.3 it.
If your git repository is unclean, then it’ll recoil in horror at the dirty, and tell you to get your act together. (Of course, if you’re not using git, then it won’t do the git stuff. It’ll just change the json and write it back to package.json.)
11: Bundle all your dependencies into the package itself
When you use the npm bundle command, npm will put all your dependencies into the node_modules folder in your package. But it doesn’t stop there.
If you want to depend on something that’s not on the registry, you can do that. Just do this:
npm bundle install http://github.com/whoever/whatever/tarball/master
This will install the contents of that tarball into the bundle, and then you can list it as a dependency, and it won’t try to install it when your package gets installed.
This also is handy if you have your own fork of something, and would prefer not to change the name.
In fact, you can run almost any npm command at the bundle. To see what’s inside, you can do npm bundle ls. To remove something, do npm bundle rm thing. And, of course, you can install multiple versions and activate the one you want.
12: Change the very laws of mathematics itself!!
There are 13 things in this list of 10 things.
npm IS JUST THAT AWESOME.
13: Always be lowercase
If you see npm referred to as “NPM” anywhere except right there in this sentence, then you know that I didn’t write it. “NPM” is the National Association of Pastoral Musicians. If you need some church music, use NPM. If you want node packages installed, then you need npm.
Other things that didn’t make this list because they were too common or not awesome enough
- Cache registry requests using etags.
- Run arbitrary scripts to start, stop, restart, and test packages.
- Set deprecation messages to keep people from using old versions of your stuff.
- compile node addons automatically if it sees a wscript file.
- rebuild packages in a single command so that you can easily keep up with node ABI changes. npm rebuild
- Manage owners of a project with the npm owner command.
- Edit package contents. See npm edit. (When used as npm bundle edit it’s especially handy.)
- Be used as a library in node programs. (Check the readme for a quick how-to, or cli.js for an example of using npm programmatically.)
Happy Thanksgiving, Americans. And non-Americans, Happy Random Thursday When All Your American Friends Are Not Online Much!
Originally published at blog.izs.me.