I was recently on the Front End Podcast (Listen to it here) with Rob Kendall. We discussed something I'm quite passionate about. Making code better! This means how to follow best practices and coding standards we have assigned and how we can do all this quickly, easily and (most importantly) automatically. So what's the secret I hear you ask! What is this magic silver bullet!
The Secret? Use a Linter!
This Static Code Analysis tool is a powerful way to keep your code in line with the latest standards and to keep a shared codebase following a set of chosen principles. We'll run through the what, how and why's explaining how you should go about implementing this solution in your code today.
The term "lint" is derived from the name of the undesirable bits of fibre and fluff found in sheep's wool.
What is it?
Linting is the name for the process of checking your code against a set of pre-determined rules. Whether those are language dependant or specific to your project. Linting will run a program or tool that will analyse the code for potential errors. It will make those warnings or errors clear to you and give you the option to fix them.
The Linting Tools Available to use.
So now we know what it is? How can we use it in our project? Surely we need a linter specific to each language! Well, you're right! But luckily, every major language already has linters available for them, and some are even language agnostic.
You can find a detailed list here: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
So, you might have heard of some of these already, but what are the benefits of using this, why should you invest your time to add these tools to your solutions?
Some of you may be thinking... what about Prettier? Prettier is not really a linter, as it doesn't check code per se. Prettier is an opinionated code formatter. It saves you time and energy and stops arguments about line length, bracket placement and most importantly, "Tabs vs Spaces".
The best thing is you can tailor it to your needs. It can be run during development or added as a step when committing to your source code repository. It's flexible enough to work around your situation.
Why should I use it?
Everybody wants to write clean code, they want to follow best practices, they want to keep up to date with the latest and greatest ways to create code.
Linting is important to reduce errors and improve the overall quality of your code. It also helps to make your code consistent over time, and across teams and individuals. It's great at catching problematic bits of code early on, and in most cases, lets you know how to fix them! Let's look at the pros and cons.
Linting will flag up any unused variables in your code. Any potentially unreachable bits of code! (Did you test an if statement by changing the logic to a 1 == 1 comparison?) It can also help to find issues with indexing beyond array lengths.
It will catch errors early, we all know the best time to find a bug is during development. The longer a bug is left undetected and unresolved, the costlier it is to fix.
Linting can produce a lot of errors and warnings. Sometimes as many as there are lines of source code. This can lead to a lot of false positives and may deter you from fixing what is really important. That's why setting up the rules, to begin with, is crucial.
Linting will identify violations of best practices. It won't teach you those best practices. Developers can use linting to improve their code, but they might not replicate the standards that are advised.
Linting is inexpensive in actual time and cost, but it can decrease developer productivity, as they fix or alter the code to conform to these rules.
How to enforce it?
So this is the tricky bit. As we can see, there are pros and cons to the notion of linting. Do you want to get your product shipped quickly or conforming with best practices that may speed up future work? There is always a trade-off, and this is something to remember.
Do you expect your team to fix all the issues every time they change something? Should they just have to keep what they have changed tidy? Maybe you just want to inform them, hoping they make any relevant changes?
The Happy Medium
What I've found is that some level of linting is useful, especially in unison with a code review process. Having basic things fixed before they go for code review means generic checks are no longer made by the human eye. It also allows us to focus on the important aspects,rather than the subjective.
We should check if we can refactor the code? Whether it would benefit from being split up, either into different files or functions? Is there sufficient documentation? Do we have tests covering important functionality? Is it scalable and secure?
I like to think that we should all follow The Boy Scout Rule - making sure to leave any code we touch code better than we found it, this means we will gradually remove any technical debt without having to do it all at once, or as specific tasks.
Leave your code better than you found it.The boy scout rule
I use 3 external libraries to aid me in my endeavours.
- Husky is the easy way to configure Git hooks. For those that do this manually, having it all set in the top-level config, standardises and simplifies the process massively.
- The next is Lint Staged. As mentioned before, you want your developers to have a happy medium of what to fix. If they are working on a file, I think we should all follow the Boy Scout Rule, meaning we clean up the code before resubmitting.
- Last, but not least. Pretty Quick will run your Prettier settings on all staged files. It's similar to Lint Staged but taking care of the formatting instead.
Install and Configure Packages
The Configuration - Package.json
The sections above add the tools installed into the Git pipelines. Husky is our middle-man and you can see that in its hooks section the pre-commit hook is configured to run PrettyQuick on our staged files and also the Lint-Staged section afterwards. This runs eslint and tslint on the globs specified, which in this case are all staged .ts and .js files it finds.
Lastly, we must set up the rules, we want to use during this process.
The important things here are the rule sets we are extending. tslint:latest and tslint-angular are taking care of the fundamentals. We can overwrite any of these base rules below, and I would recommend finding that happy medium for yourself. I have left a couple of rules that make sense for me.
tslint-config-prettier is required so tslint does not format our code, that is Prettiers job and where the prettier config comes into play.
The best place to put your prettier config is a .pretterrc file. I have shown a simple set of rules to get you started. The Prettier Documentation of Configuration is the best place to look for tailoring the setup to your needs.
Here it is in action. You can see a git commit kicking off husky which in turn runs our tools! First Prettier fixes up any formatting, before eslint changes the let to const as it's never reassigned, and moves our class level declarations to the top of the file! Pretty neat right!
So in conclusion, hopefully, you've understood what linting is, why to use it, and how to adapt it to your coding environment!
I would love to hear of any other setup that works for you! There is always room for improvement. Please share your thoughts below!