Node.js — How to test your new NPM module without publishing it every 5 minutes

I must admit it took me longer to figure this out than it should have, but I did figure it out on my own, not that there was much to figure out. So perhaps others are in the same boat I used to be in. The reason I didn’t know this most obvious “trick” was because every single module I used/installed came from NPM! I had never required a local NPM module before, even though I had even written and published some myself already (shame on me)!

First we will discuss how to require other projects locally, using an absolute path, then we will discuss the much more useful and streamlined npm link functionality.

npm link  # for the win

So, you’re developing an NPM module, let’s call it “Viking”, but let’s be more exact since NPM probably doesn’t accept uppercase characters, so let’s call it viking. And you want to eventually publish viking, and you need to test it while you are writing it. Perhaps you want to test it to completion before publishing it at all. (I am known to publish projects early to make sure I get the namespace on NPM before someone else takes it, LOL, shame on me!).

We can and should write some tests in the viking module project itself, but at some point, it’s probably a good idea to open up a new NPM project (with “>npm init”), and install the viking module which is currently in development on your local machine. Let’s call this secondary project, which is designed to directly test our viking project, “Tudor”. tudor depends on the viking project.

The problem in general, for the naïve observer, is that you would then have to publish the viking module, and then use “npm install viking” in the tudor project. Not only that, but every time you make any changes to viking, you will have to publish it to NPM and then re-install/update it in tudor. Not pleasant to say the least.

However, there is an easy way around this, which is totally obvious if you have half a brain (unlike me).

Some of the savvier Node.js devs out there know you can require a file in a folder by naming that file index.js and just requiring the folder that contains that index.js file. By an extension, you can require that same index.js file (or whatever you call it, by simply requiring the root of the directory that contains the package.json file (make sure the main property in the package.json file points to the “index.js” file, wherever it is located in your project, for many projects it is ./lib/index.js).

This is the essence of packaging and importing code in Node.js-land!

So, in our Tudor project, the old way to test the Viking module was like so:

While developing Viking/Tudor, an improved way of doing so would be to use:

As you can see, we can easily require the local project and bypass NPM entirely until we are closer to ready to publishing it :) I use the absolute path because it’s a bit easier to work with, and there is really no reason not to.

I have, and many of us have, been spoiled by NPM and how easy it is to use. But now, if you didn’t know already, you know how to use local modules.


Next: NPM Link functionality

Now, using absolute paths to develop local modules is actually just a step towards understanding what’s going on a little better. It’s really not a good solution. Instead, we should revert our code to the original (without absolute paths) and use “npm link”, like so:

cd <viking-project-root>
npm link # this should install a global symlink to the local project
cd <tudor-project-root>
npm link viking # will create a symlink locally to the global viking # symlink
# voila! now we can develop the two projects side-by-side without   # having to worry about publishing either of them

You can read more about npm link here:

Note that NPM link works fairly magically, but that it will update the relevant files in any given projects node_modules directory, such that I doubt NODE_PATH is changed on your machine, but symlinks are used, symlink-ing your local project to the globally symlink.

Once you get a handle on “npm link”, you will realize that it works super well, I have had no problems with it at all. The only problems I have had is publishing modules after using some symlinking, but I am sure it’s because I misusing something. npm link works great!

NPM Link Up tool

I wrote a really useful NPM link tool, called NPM-Link-Up, useful for complex projects with multiple locally developed packages:

Definitely check it out if you have more than 2 locally developed modules/packages that must be integrated. You can also check out something called Lerna and Rush which are different kinds of tools used to solve a similar problem.

A side note:

If you want to debate politics or discuss libertarianism, anti-communism, personal liberty, soccer, and pretty much anything, don’t hesitate to reach out to me on Twitter @the1mills. All code all the time, does not a well-rounded person make.

Extra credit

For extra credit and bonus points, you should read about NODE_PATH here:

https://nodeolyk.wordpress.com/tag/node_path/

https://lostechies.com/derickbailey/2014/02/20/how-i-work-around-the-require-problem-in-nodejs/

Show your support

Clapping shows how much you appreciated Alex Mills’s story.