Hiring a gardener to trim the weeds: Adding a linter halfway through building an application.
In this piece I am going to talk about a recent real life scenario that occurred to me, and how with a few handy tools on npm, I managed to add a linter (and enforce the rules), without much of a headache, to a project that was already a living, breathing creature.
Everyone loves an analogy…
Planning ahead, looking at the bigger picture, and determining what procedures to put in place can help resolve an awful lot of problems in tech (and in life, in fact!). One of the most overlooked, in my opinion, is agreeing on and implementing a code style, and potentially adding a linter to enforce, check and help keep that code style consistent and clean.
An analogy I like to use is to think of your budding new code base as an empty garden. If you plan where the different seeds are going to go, and how they will grow together, then planting, building and cultivating goes a lot easier!
Sometimes it doesn’t seem like a suitable use of time, or external deadlines might impact the priority of adding a linter from the very beginning. If the owner of the land wants carrots before Christmas, then planning where the sunflowers are going to be planted can wait until after the carrot seeds are down, right? That’s all well and good until it’s Spring and the ground the carrots have been grown in are exactly where the sun would work best for your sunflowers.
Fear not! It’s not too late and just as it’s possible to get a gardener in to look at, trim and sort your hedges, flowers and veg it’s perfectly doable to add a code linter to a codebase and retrospectively fix any issues with code cleanliness that have been introduced.
The tech stack and the problem
In this example I’m using a React frontend with state management (the type is not important for this piece), using Javascript over Typescript. the code was mature enough to have a lot of commits, branches and contributors, but still young enough to be considered in alpha (at a push!)
I noticed that 90%+ of our pull requests were getting changes requested. Of these there were the classics (“Why is this called blahBlahBlah, it should be called plahPlahPlah?” etc.) but most of the comments were “missing semi-colon” or “indentation”. Most of the PRs weren’t failing (or having changes requested) on a single line of code change, per se, but were in fact all getting sent back for reasons purely down to issues that were to do with code cleanliness. Based on that, as a technical debt task, I opted to add a linter to the code base.
Adding the linter
After a bit of consideration of the pros and cons of a few, and based on my personal experience with linters in the past I opted for ESLint and using just a few CLI lines, got our linter installed, configured and set up (I’ve missed out the boring bit where I created our .eslintrc
file). Due to the structure of our application I was also installing babel-eslint
for the parser
npm install --save-dev eslint babel-eslint
npx eslint --init
npm run lint
Easy! We have a linter, and we can start looking at using it to sanitise our code. I can even start looking at adding it to my continuous integration pipeline and failing builds if… Oh…
That’s an awful lot of problems to solve. Fear not! ESLint has a nifty --fix
option which will let me remove all the warnings, and leave me with (only!) 138 errors to fix… Oh wait… If I put a commit up with 2313 line changes for lint fixes only a madman would read that and not be angry. So I can’t use --fix
and I’m going to have to manually fix my lint problems on a case by case basis!
The third option: ESLint-nibble
So I can’t realistically just run eslint '[YOUR FILES TO LINT]' --fix
without making a bunch of enemies in the office for a many-thousand line change PR, and changing on a case by case basis means an awful lot of my valuable time scanning code which compiles perfectly well for slight aesthetic tweaks (it’s no wonder people consider it a waste of time!). There is, fortunately, a third option. Enter ESLint-nibble.
ESLint-nibble is a way to individually iterate through your lint errors by the rule that is being violated, and attempt to autofix them. It allows for a piecemeal way to split the boring lint changes into separate commits or pull requests, so as to not overwhelm your reviewers, whilst also allowing you (very handily) to focus on the lint catches that might actually help optimise your code.
Crucially, it’s a tool to be used, so shouldn’t be saved to your package.json, and can be discarded when done with!
Firstly, in your package.json file you’ll need to add the following script:
"nibble": "eslint-nibble '[YOUR FILES TO LINT]'"
and then in your CLI run
npm install --no-save eslint-nibble
npm run nibble
It’ll churn up, analyse your linting problems via ESlint and then work it’s magic:
Now you are able to trim those weeds, with the help of a handy gardener, to get your codebase back in lint-worthy standard, without wasting your own time, or making your reviewers feel like they want to unscrew all the pieces of your computer chair very slightly for when you next go to sit down!
ESLint-nibble is by it’s own definition a tool to be used to get on top of your linting. Once your code is up to scratch it shouldn’t really be used again. At that point eslint '[YOUR FILES TO LINT] --fix
should do the trick (or of course you could manually do it, to learn the lessons that little bit better!).
One final point: Before using ESLint-nibble, I would recommend setting up your .eslintignore
file to make sure you don’t fix those files you aren’t bothered about linting!
The result
Using ESLint and ESLint-nibble I managed to add a linter to a live application, and run and fix the issues (bar some very bad ones that needed a bit more refactor work) in the space of a couple of days. Now our application has a working linter to help code standards, and hopefully our garden won’t get so overgrown and disastrous we need to hire a professional again.