Let's Build a Thing: NPM Dependency Checker - Part 1
It’s expected that you know how to use Git, terminal and have Elixir setup on your machine. The MASTER branch on the repo has the latest up-to-date code. To see progress along the way, checkout one of the other branches.
[Refactor Warning]: As is often the case in development, we refactor as we go. In part 5 of this series, I performed a major refactor and a good portion of the code was changed. Rather than present the “final” version in my let’s build series, I’m electing to show the iterative process of development.
The other day I was at work and making changes to some of our core packages. One package I installed wasn’t working properly. Why? Because it required Babel 6 and we were on Babel 5. If you’re familiar with Babel, you know that going from 5 to 6 isn’t just a simple install swap (especially on a good-sized enterprise app).
But the issue didn’t stop there. I then decided to undertake the upgrade. Along the way I needed to add another package to our dependencies, but it didn’t work. Why? Because it required a version of React that was beyond what we had. While going from React 14 to 15 isn’t overwhelming, I was starting to go down this rabbit hole of upgrades.
At that moment I decided that it would be nice if I could have typed in a package name and received a list of everything it (and it’s dependencies) needed. I could then scrub to find out if, for example, something needed Babel 6. But beyond that, I wanted to know just what exactly I was using when I did “npm i” for a package and I wanted to know before I installed it.
I didn’t find a tool that did this (and a couple other ideas), so I decided to build one. And even if the tool exists, I think this makes for a fun, hopefully small, application to write in Elixir.
Ok, let’s do a mile-high flyover on this upcoming app to see what we’re going to need.
- I’d like to use it via the command line so I can just do this:
- I’d like some sort of indicator that it’s working (progress notification)
- I’d like it to be as fast as possible. At first, I just want it work, but it should end up concurrently grabbing all the package info.
- I’d like the output to be easy-to-read in the terminal, but I’d like to be able to pass in an argument to store it into a file (for those who don’t want to >>)
- Create a dependencies list and add the initial package to it
- Grab a package’s repo url from NPM (using NPM view ideally)
- Go to the repo url and fetch package.json
- Scrub package.json for dependencies (both dev and normal)
- If the initial repo isn’t found, it should explain this and quit
- If the initial repo is found and there are no dependencies it should explain this and quit
- If the initial repo is found and there are more dependencies, it should now iterate through them and do:
- Check if the package is in the dependencies list. If so, do nothing else for this package.
- Grab the package repo url
- fetch package.json from repo
- scrub dependencies
- add this repo to the dependencies list as it’s now complete
- proceed to iterate through these sub dependencies as above
- Once all checks are complete it should report the findings
In the above I said “list”, but I’m thinking a struct because I’m going to want some associated data (name of package along with version(s) and maybe a counter for # of times it’s depended upon).
Now that we have the general concept of this application along with an idea of how it should operate, it’s time to setup the project and get to coding.