Reliable Continuous Integration in JavaScript

Picture of the author
Nicolas CharpentierJanuary 18, 2017
4 min read
Reliable Continuous Integration in JavaScript

When you build a piece of software you want to build a reliable one, so often you’re using various continuous integration tools, such as CircleCI, Travis, Shippable, Codeship, AppVeyor, Semaphore, Jenkins, and Bamboo.

But, is your continuous integration process is as reliable as you think?

I’ve seen a lot of people on their continuous integration cache or reuse the same node_modules between builds. What they want is a fast pipeline, but more often than not this is done to the cost of a trustworthy CI.

— Have you ever heard this when your application act strangely ?

You should delete your node_modules folder and redo a npm install.

— Because I do, and way too often.

Do I be honest or nice?

The node_modules folder is not as reliable it could be

You may want to clean it up sometimes, because it seems to get clogged with time, especially on a testing environment.

What is the expected lifetime of the node_modules folder?

Lifetime of the node_modules should be for the current build, unless you often run some sanity checks.

Extraneous Packages

npm prune

If you don’t know this command, you should probably read this and run it into your development folders.

This command removes “extraneous” packages. Extraneous packages are packages that are not listed on the parent package’s dependencies list.

So, let’s say for example that in an application I add a dependency named potato, I commit and I push. CI will run and install potato into node_modules folder. Now, let’s say I remove that dependency from package.json. Since it’s already installed on my machine and the CI container, it will work fine.

If I clone the repository again or another developer tries my repository, it will not work as expected. However, it works on my machine and the CI is green. So we need to put the whole project on hold until we can resolve the issue. Finding and resolving the issue can be both time consuming and frustrating especially if there’s only two devs involved.

— You’ve probably heard this before :

Yeah but it works on my computer

— We certainly do not want to hear that

The role of the CI should be to validate that an application works well from a fresh installation.

That’s why you should always clean node_modules and do a npm install or at least run the prune command.

If an install worked on one system, it should work exactly the same way on any other system

Git Dependencies

If you use a dependency that isn’t published to NPM like a git URL, your dependency won’t be updated by npm install if the version wasn’t updated, even if you commit to master or your specified branch/tag/commit.

That’s why clean install should be privileged, you certainly don’t want to test your application with an older dependency version.

Yarn to the Rescue

Yarn Logo

If you want an ultra fast, mega secure, and super reliable solution, Yarn will be yours

Fast

Yarn caches every package it downloads so it never needs to download the same package again. It also parallelizes operations to maximize resource utilization so install times are faster than ever.

Reliable

Using a detailed, concise lockfile format and a deterministic algorithm for installs, Yarn is able to guarantee that an install that worked on one system will work exactly the same way on any other system.

Secure

Yarn uses checksums to verify the integrity of every installed package before its code is executed.

Moreover, Yarn doesn’t require additional steps to prune extraneous packages, yarn install will do it automatically on each installation.

Also, Yarn resolves git tarball like a charm.

Conclusion

So basically, just install Yarn and replace npm install by yarn install to considerably increase the trust level of your CI.

If you want to reach the top trust level, be sure you run yarn install on a clean environment. The cache provided by Yarn will do the job for you, don’t forget to keep the yarn cache and not the node_modules folder across builds. See here how to do it.

Thank you!