Discover the power of linting in development with ESLint, Stylelint, SonarLint, Sheriff and Prettier. Error corrections, code analyses and efficient projects - quality on a new level.
The world of software development is dynamic and demanding - with a multitude of frameworks, libraries and technologies that are constantly evolving. But even with the best expertise and the right tools, ensuring code quality can be a challenge. This is where the power of linting comes into play. Linting tools such as ESLint, Stylelint, SonarLint and Prettier offer not only bug fixes, but also comprehensive code analysis that takes the quality of your codebase to a new level and ensures that it is maintained.
In practice, linters have helped me to write better code and saved me countless minutes of looking at changes in a merge request. Which occured due to the fact that the line break had changed.
In this article, we’ll explore why linting is so important, the benefits it offers and how these tools help make projects more efficient and of higher quality.
A linter is a programme that gives the developer feedback on potential programming errors, style problems or anti-patterns1. Fig. 1 shows you a linter in action.
But what problems does Linting actually help us with? Here you have an advantage for every finger on your hand, in case you have to discuss with your project manager whether the time invested is worth it 😉.
This is an overview of linting tools that I use in my daily work. Feedback is of course welcome ✉. I write here about the concepts and ideas behind the tools for static code analysis. If you want to see a concrete implementation, check out my Configure Angular Linting post.
This is an open source linting project (eslint.org). It is highly customisable and helps to find and solve problems. These can be bugs, unimplemented best practices or code-sytling problems 2.
At the heart of ESLint are its rules. A rule defines a certain expectation of the code. An example of such an expectation would be to generate a linting error if a constructor
contains a return
statement, see Fig. 1.
This is achieved using the no-constructor-return rule. It can be easily integrated into eslintrc.{js,yml,json}
, the ESLint configuration file.
However, ESLint shows its true potential when existing rule sets are integrated. One outstanding rule set is eslint:recommended, which contains a large number of tried and tested rules. The exact rules that activate this set can be found in the official ESLint documentation.
At first glance, Prettier appears to be more of a formatter than a linter3. It takes care of:
Prettier also offers the advantage that the configuration options for formatting are limited to a minimum. Why this is an advantage is explained in detail by the Prettier team in their article why-prettier?.
Prettier can be integrated in two different ways, but both achieve the same end result.
One approach is the npm-package prettier.
Before:
const blog = { name: 'j1n', url: 'https://j1nk3e.de/', articles: 400, visits: 2, faviconDir: 'assets/favicon.ico' }
After:
const blog = {
name: 'j1n',
url: 'https://j1nk3e.de/',
articles: 400,
visits: 2,
faviconDir: 'assets/favicon.ico',
}
The lines of code that contradict the prettier formatting are adapted and not shown as in Fig. 1.
The other way is via ESLint. It allows us to execute the prettier rules as extensions via ESLint. This is particularly easy with the npm-package eslint-plugin-prettier. ESlint would then mark each violated prettier rule as in Fig. 1.
Similar to Prettier, the .editorconfig
helps us to maintain a consistent formatting style. Different rules can be defined, which then override the respective IDE settings4.
In EditorConfig Github-Wiki you will find an overview of which rules can be configured.
It depends on the IDE whether a plugin is required or not (Overview).
The difference to Prettier is that EditorConfig determines the settings of the IDE.
Let’s take the indent_size
(EditorConfig) or tabWidth
(Prettier) as an example. In the .editorconfig
we can set the indent_size
to indent_size=10
. One tabulator then corresponds to 10 spaces, for example. If we now use Tab in the IDE, 10 spaces are set. This contradicts the prettier rule "tabWidth": 4
(set in .prettierrc
).
Prettier normally takes the .editorconfig
into account, but not every rule from the .editorconfig
can be transferred to the configuration options of Prettier.
To summarise, the difference is that the editorconfig affects the code we write, while Prettier formats the code we have written.
The optimal use of EditorConfig and Prettier results in an effective synergy.
If we align our EditorConfig settings with Prettier accordingly, we ensure that our code is formatted correctly directly during writing (see the example with indent_size
). This makes reformatting by Prettier unnecessary in this case.
As a result, Prettier will “only” mark lines of code that are not covered by EditorConfig rules.
Sheriff enforces module boundaries and dependency rules in TypeScript. It is also an extension for ESLint.
Every folder that contains an index.ts
has to be considered as a module. This also applies to the following folder structure.
project
│
└───feature1
│ │ internal.service.ts
│ │ index.ts
└───feature2
│ service2.service.ts
A function is exported in the internal.service.ts
file. The index.ts
in turn exports the internal.service.ts
.
If service2.service.ts
were to import directly from internal.service.ts
, this would cause the linter to be flagged via ESLint using the sheriff rules.
// in service2.service.ts
// deep-import Fehler
import { FUNCTION } from '../feature/internal.service';
// valider import über index.ts
import { FUNCTION } from '../feature/internal.service';
Sheriff enables the configuration of access rules between modules. This is particularly useful for the implementation of domain-driven design (DDD). An example can be found in the sheriff-gitHub-repo.
Take a look at the YouTube video in which one of the developers introduces Sheriff.
Stylelint is a powerful linting tool specifically designed for checking Stylesheet-files. It offers a variety of rules and configuration options to ensure that the code complies with the defined coding standards5. As with ESLint, rule sets or plugins can be imported, making Stylelint the ESLint for Stylesheet-files. Stylelint must also be harmonised with Prettier from the ruleset side (mutually contradictory rules) if you are using Stylelint below version 15; this can be achieved quickly using the npm package stylelint-prettier. Otherwise, the conflicting rules are already deactivated from higher versions onwards.
stylelint-order is one of the importable rule sets for Stylelint. As the name suggests, this determines the order of the CSS properties in stylesheets. There are several configurations on the basis of which the CSS properties should be ordered.
This is a really big advantage if you are working with several developers on a project or with older code, as you always have the same sequence of commands in the stylesheets.
Last but not least - SonarLint, a tool from Sonar. Sonarlint is a particularly comprehensive tool. It goes a little further than ESLint, which focuses more on Javascript and Typescript2. Sonarlint also analyses HTML pages for code smells, among other things, and is therefore more comprehensive than ESLint, although there are some overlaps.
<table>
</table>
For example, the code above would be linked because the table
does not contain a <caption>
or <th>
element.
When looking at the advantages of linters, it is impossible not to realise that - whether a solo or large-scale project - linting is part of the foundation of a project and therefore essential. On the one hand, it is the continuous maintenance of the highest possible standards that the code must fulfil and, on the other hand, the massive time saving and learning effects. Furthermore, the factor of learning through the linter and, for example, the permanent avoidance of code smells should not be underestimated. With my selection of tools, we cover the majority of files and leave hardly any room for avoidable errors.
I hope I was able to convince you to use Linter from now on. If so, I recommend that you run Linter “on-save”, in a pre-commit hook and again in the CI/CD of your project. It will be interesting to see what new technologies will achieve in this area. I could very well imagine AI expanding the list of Linter benefits.
Do you have any questions or perhaps even ideas for other linters that I should include? Feel free to send me an e-mail.
SonarSource: What is a linter?, in: SonarSource, without date., https://www.sonarsource.com/learn/linter/ (visited on 01.10.2024). ↩︎
ESLint: Core Concepts, in ESLint, without date., https://eslint.org/docs/latest/use/core-concepts (visited on 01.09.2024) ↩︎ ↩︎
Prettier: Prettier vs. Linters, without date, https://prettier.io/docs/en/comparison (visited on 01.09.2024) ↩︎
EditorConfig: What is EditorConfig?, without date, https://editorconfig.org/#overview (visited on 01.14.2024) ↩︎
Stylelint: Stylelint, without date, https://stylelint.io/ (visited on 01.14.2024) ↩︎