No one sets out to write ugly, inconsistently-styled code. It just sort of happens.
Even as the only developer on a project, the more time that passes and the more code you crank out, the harder it gets harder to maintain a consistent code style.
That’s why you need a style guide.
I’ve experienced first-hand how much more teams can accomplish after adopting a style guide.
You no longer need to make little style judgement calls throughout the day. Just consult the style guide.
And when a teammate needs to maintain your code, it’s clean code that they can read and understand.
Adopting a style guide is one of the easiest things you can do to boost your code’s maintainability — which ultimately boosts your team’s productivity. So let’s explore the most popular way to do this.
Enter AirBnB + ESLint
But as the ecosystem matures, experienced developers start to yearn for “the standard way” of doing things that more solidified ecosystems offer.
For more details on adding ESLint to your project checkout this link.
Once you have that squared away, you can configure your project to enforce AirBnB’s style guide by installing their npm package:
npm install --save-dev eslint-config-airbnb
Add the following line in your .eslintrc file
Standards are overrated
While I agree with most of the rules in the style guide, here is a list of overrides that I compiled. This is what the .eslintrc files in projects’ root folders look like:
Let me explain the reasoning behind each of these customizations in detail.
The tabs VS spaces war can potentially ruin friendships, and possibly even sabotage romantic relationships.
I prefer to indent my code 4 spaces, even though a vast majority of configs out there prefer an indentation of 2.
My reasoning is that in order to write clean code, larger indentations give you a better visual representation of how deep the nesting is in your functions, and how many different branches you have.
Also, indentation is one of the rules that breathes more “air” into AirBnB’s default style guide. As a result, your code doesn’t crowd on the left side of editor so badly.
This is probably the biggest deviation from the standard. I hate crowded code. I started writing code with extra space padding more than 2 years ago, and I never looked back.
So what do those rules mean? Well, have a look at the following code. It technically respects the rules of AirBnB’s official style guide.
I know, it’s a bit confusing. I tried looking for a medium complexity function from one of my codebases, but I had to obfuscate a lot of it, so don’t try to understand the logic behind the code (because there is none). Just try to read it. Try to focus, for example, on variables that are used in multiple places, when parameters are passed to functions, and where the function calls are.
Now have a look at the same code, but with the extra spacing rules applied:
I’m not saying that it’s highly readable now, but you can more easily identify where you have parameters sent to functions — especially around the curried functions.
Also check the difference between the 2- and the 4-space indentation in the two examples.
At first, these techniques might not seem like a big improvement. I encourage you to give them a try. I think you’ll quickly experience what a difference this makes.
While the first two categories had some clear arguments, I must say that the single vs double quotes decision is a highly subjective one.
One thing I’ve noticed is that you’re much more likely to need to write a single quote inside a string of English text than a double quote (“I’m here”, “Don’t do that”). So double quotes might be more convenient in these cases.
The official AirBnB style guide has a “no-use-before-define” rule, which throws an error if you try to use something before you define it. This is a good rule — especially for variables — because you should not rely on hoisting, and you should keep the temporal dead zone problem in mind when you use let and const.
I prefer to allow functions be used before they’re defined. The reason is simple: most of the time, you will break your functions down into smaller sub-functions. However, the “no-use-before-define” rule will tell you to put these sub-functions before the original function.
But your sub-functions are there to abstract parts of the algorithm. They should not bother you when you open a file containing your top-level function, which you use outside of the file.
Of course, this is debatable. But it does impact debugging. When you iterate over some code, and you find a call to a different function, ideally you should be able to look below it, or — worst case scenario — scroll down through a few sub-functions and find what you’re looking for.
This, in combination with AirBnB’s function declaration against function expression rule, can give you the freedom to structure your modules or function libraries as you like, while ensuring you don’t accidentally call an uninitialized function.
Const over let
Here’s another small deviation from the style guide. You can notice in my config:
In the AirBnB config, this is set to 2, which stands for error, while 1 stands for warning.
Regarding my deviation, I prefer a warning, because there are situations in which you do not change the assignment of a variable, but you change a lot of its content.
Have a look at this code:
The rules will tell you that this is right — hash should be const because it is not re-assigned. But this never really made sense to me. I should be aware that there’s a great deal of change happening inside hash.
So I will use let to signal the fact that the variable is subject to change. const and let should lend more meaning to your variables, and should not hide the truth in any way.
You can cyclomatic code complexity to compute the complexity of each of your functions.
Deciding on a max level of complexity is tricky. Ideally it should be as low as possible, meaning that your functions should have at most 1 or 2 branching possibilities.
It makes sense to have that number as low as possible from the perspective of code reuse and testing. But there are times when it’s harder to break functions down. That’s why I see the complexity more as a warning then as an error.
The important thing here is to limit the number of functions that reach that maximum complexity limit. Even in a medium-sized codebase, I wouldn’t like to see more than 10 functions that break this rule. So I picked the maximum value of 5, in order to highlight those functions. I’ll target these functions when I have time to do some refactoring.
Complexity can be solved in multiple ways. Refactoring into smaller functions is the obvious one. Another option is transforming your switch statements into mapping assignments.
We had several debates inside our team, and we ended up using 5 as a reference value for the max complexity rule. But in some cases we go down to 4, just to be sure that we are writing clean and simple code.
A note on React
Because I work a lot with React, and the AirBnB config also contains a hefty number of rules in that area, I wanted to include some of my preferences on these here, too.
Finally, related to class vs factory components, I tend to prefer the latter. I see no advantage to using classes at this point. I may write a future post expanding on why I feel this way.
That’s about it! I hope you enjoyed reading this. I welcome your feedback below.
If you liked the article, click on the green heart below, and I will know my efforts are not in vain.