The default package manager for node is called npm. Apparently it doesn’t stand for Node Package Manager but it sure seems like it should. Npm brags that they have have hundreds of millions of downloads per month. However that includes download from build servers and from package restores and doesn’t map to the number of people typing
npm install tsc |
There are a number of limitations and issues with npm, however. One I hear frequently is that it is slow to download. That’s for sure. I pulled up project I have and found that running npm install consumed a full minute of the build (71 seconds on average, actually). The only thing in the build which took longer was the actual compilation of tens of thousands of lines of code. Once I enabled parallel builds that actually reduced the compilation time to less than the package restore.
Speed is actually a secondary concern to me. It is nice to have fast builds but you’re company is unlikely to succeed or fail based on the speed of restoring npm packages. The big limitation of npm in my mind is the fact that two developers running npm install off the same packages.json might end up with different versions of some libraries. This is because dependent packages can have wildcard version rules whic resolve to different versions depending on when the install is run.
There is npm shrinkwrap which generates what is, in effect, a lock file fixing on a particular version of a pacakge. Tut it must be manually run after each install to make sure it is up todate.
Facebook, who are really quite innovative in the JavaScript space despite having writting much of their terrible site in PHP, created and released yarn. Yarn substitutes in for npm and brings increased speed as well as a lock file which is automatically updated. This will eliminate the possibility that two installs will get radically different node modules installed, possibly breaking the software.
The speed it gets in two ways. First it does parallel downloads instead of serial and second it performs caching by default.
In order to pull yarn in I simply installed it, ironically using npm.
npm install -g yarn |
The ran it in my project directory
yarn |
That created a lock file, yarn.lock
. I check it in and changed my npm install
on the build server to yarn
. That was it. As yarn caches the first build was about as slow as the previous but with the cached established thing got much quicker. The npm step (now a yarn step) of my build improved to 22 seconds from 71. All while improving reproducibility. Jolly good.