Testing npm packages

When you are developing on an npm package locally, you would like to make sure your changes are working as expected by trying them out. Turns out, this isn't a small feat. Let's talk about the different approaches depending on the type of changes you made.

Testing normal changes

For starters, if your local changes does not have anything special to do with the package's lifecycle – such as installing, building and publishing, more on that later – trying it out locally is easy.

Create a testing / playground project that could be as simple as an index.js and package.json. Next, let's require (or import for you fancy ES6 people) your modified package locally using the handy npm link. You should be able to test it by as simple as printing the require content in logs.

A word of caution: the npm link approach simply creates a symlink. It does not execute any npm lifecycle scripts, such as build or install. Let's explore how to test those changes in the next chapter.

Testing lifecycle changes

While npm doesn't have an official documentation on this, when we talk about lifecycle changes I'm talking about these npm scripts. If you are developing features that rely on or interfere with one of the scripts, special care should be taken when testing them out.

Packing

Some changes are relying on the npm package's packing / building process. For example, a common one is to invoke scripts to generate the content inside dist/ folder. I recommend using npm pack. This allows you to generate the package's tarball, as if it's ready to be installed. Then you can unzip the tarsal and inspect the dist folder.

Publishing

Another common problem I've found is to test features that are only run before or after the publishing. For example, one of the npm packages I worked on needs to match its to-be-published version with another package on the official npmjs registry.

Before running anything, the first thing to make sure is we have the correct version of npm installed. Because there are some subtle discrepancies (gotchas) that will introduce unexpected behaviors if not careful. The npm script prepublish was an infamous example..

There are many approaches to test package publishing. The easiest method, and the method I recommend, is to just change your package name to something private and publish to npm registry.

For example, if your package's original name is lodash, I would just rename it as vzhang-lodash; or even better, publish it under your own scope, such as vzhang@lodash, to avoid polluting the global namespace. The package's lifecycle method should work exactly the same, just remember to use the new modified name when installing or requiring it.

Yes, you will probably end up publishing it every 5 minutes, sorry Medium authors. But I would argue that the simplest solution is the least prone to breakages. In fact, this isn't against the philosophy of npm. Its official documentation recommends us to not be stingy on package names: "There is plenty of room on the registry."

Publishing, advanced

What if your package is so complicated that you can't simply just change name and publish to public registry? For example, your package may depend on some packages from private registries, and putting it out there in the public registry just won't work.

This is a valid excuse to use third party tools to simulate publishing. Here's a few. Full disclosure: I have yet to try these tools myself, but I have heard good things.