On April 27th, we did a webinar called Linter Configuration and Best Practices to Improve Code Quality. Guest speaker Jeroen Engels, Senior Software Engineer at CrowdStrike and author of elm-review, joined Lorenzo Gabriele, Software Engineering at Codacy, in discussing code linters. During this talk, they covered the following:
- Code quality and the role of code linters;
- Manual vs. automated linter setup;
- Automatic fixing;
- Pros & cons of disabling errors locally;
- And much more!
In case you missed the webinar live, don’t worry: you can (re)watch the recording here or below 👇
A live talk on code linters
You can check the detailed talk on our video recording – we even give you the specific time frames! But we’ve summarized the topics for you to read 🤓
What is code quality? Does it mean the same to everyone? (00:03:11)
One way to define code quality is how reliable your code is and how easy it is to change. Of course, if your code has a lot of bugs, it has low quality. However, if the code does not have bugs but it’s hard to maintain, it does not have high quality either.
Reliability and ease of change are two qualities the code needs to have. They depend on familiarity, which linters will help you with. Linters will try to find bugs, but they’ll also make your code more consistent and familiar. If you want to have code that is easy to change, it needs to be familiar to you in the code style of the entire codebase, and it will be easier to maintain.
Why are linters an essential tool for software development? (00:08:15)
As developers, we have to maintain code, and we have to fix a lot of bugs. As we grow more experienced, we go from fixing bugs to preventing them from happening again. We’ll reach for tools that help us in that process and guarantee our code behaves as it should. Code linters are one of those tools.
A code linter is very useful, as it looks at the codebase and tries to find problems or inconsistencies. However, linters are only one of the tools you should use. To guarantee good code quality, follow Test Driven Development or other similar practices, and use type checkers. In combination, these tools can be very powerful.
What is the difference between a linter and a compiler? (00:11:31)
A compiler needs to be objective. It will tell you if there’s a problem in your code that doesn’t allow the compile to transform your code into valid binary, for example. They are generic and work for all possible valid programs for a specific programming language.
On the other hand, a linter can have a more subjective nature, especially because you can (and should) configure and customize it. For example, you can adapt linters to your code style and write custom linters rule that makes sense for your projects.
Setting up a linter requires work. Is it always worth it? (00:15:55)
As a general rule of thumb, having a linter is always worth it. If you’re very pressed for time, you might not be able to configure the linter right away, but investing in tooling is invariably a good idea in the long run.
However, there are other reasons for not setting up a linter. For example, when the linter is bad, it reports many false positives (i.e., when it says there’s an issue, but it is not real). This makes developers waste their precious time. Another reason is when the linter is unnecessarily hard to configure.
Furthermore, the amount of code you write in a particular programming language also affects your decision to use a linter. If you have a programming language you rarely use, it’s not worth spending a day perfectly configuring a linter.
This is where tools like Codacy Quality can help. You can let Codacy Quality auto-configure the linters for you and give you good defaults so that you can focus on something more valuable for you. But, of course, if you use a linter daily, we advise you to configure the linters for your specific needs.
Choose your rules wisely, talk to your team about which rules you want to enable, and ensure they are satisfied and everyone will be happy. If you’re pressed for time, you can start with a few rules, add them individually, and adjust over time.
Can linters be used as a learning tool? (00:25:54)
Most developers don’t start a program from scratch; they inherit code that other developers previously wrote. But imagine you’re starting, using new technology, and wanting to follow the best practices. In that case, a linter can help you as a learning tool.
Let’s use JavaScript and ESLint as an example. You can use the default configurations for ESLint since several projects use them and are satisfied with them. This alone will help you guarantee the consistency of your code, and your codebase will be aligned with the JavaScript community. Plus, it will help you learn new patterns and best practices.
Is automatic fixing a good option? (00:28:45)
Automatic fixing is a great feature because it saves developers a lot of time. But with great power comes great responsibility. You should not accept fixes blindly after looking at them and understanding the error. If you just use automatic fixing, you’ll not know which errors were reported, why they were reported, how they were changed, and whether those changes were correct or safe.
With bad linters, automatic fixing could be even more dangerous. When an automatic fixing linter tells you a lie and applies the lie, you’ll commit the lie.
At Codacy Quality, we get auto fixes from, for example, ESLint, but instead of applying them to the code, we parse them, and then report them to users as GitHub comments. These comments have suggestions, and then the reviewer or the developer can apply the suggestions manually by committing from the GitHub UI.
Is it advised to disable linter errors locally, in a single place of your code? (00:37:38)
As a rule, you should not disable linter errors locally. There are four main reasons why you would want to use suppression comments. As we discussed, one of them is if the linter reports a false positive. In that case, the proper solution is to improve the linter, go through additional configurations, or rethink the rule in the first place.
Another reason for using suppression comments is when you have effective false positives, so real errors, but maybe because you disagree with the rule and therefore disagree with the error. In that case, the solution is to understand whether the rule is helpful for your project. The other case where this can happen is when the rule is correct, but you need help understanding the problem. That can be an issue about explaining the error, with the linter having a bad error message.
The third reason for using suppression comments is that when you’re pressed for time, you want to ship a feature without making the correct approach.
Finally, the last reason for using suppression comments is when you want to introduce a new rule to your codebase, but it has a lot of existing errors. Some linters, like Elm Review, allow you to create a baseline and ignore all the existing errors for some time, and they only report on new ones.
Q&A time
After the talk, we opened the floor to all the questions the audience might have. We were delighted to receive a tone of questions! We’ve listed them for you:
- Why do linters label auto-generated code as being low standard on Codacy? (00:14:01)
- What are some best practices for integrating linters into a development workflow? (00:48:03)
- What data or indicators do you use to determine when a rule is more of a disturbance than helpful in terms of productivity versus consistency and quality? (00:49:26)
- Can you give us five linters a developer must use? (00:52:34)
- Can you talk about other techniques that can be used with linters to improve code quality? (00:56:21)
- How do you handle when new people join your team, and they disagree with the existing rules? (01:01:44)
Thank you to everyone who joined live and those who watched the recording later on! Let’s keep the conversation going in our community.