What is linting?
Generally speaking, linting is a tool for static code analysis and therefore part of white-box testing. The main purpose of white-box testing is to analyse the internal structure of components or a system. To make sense of this, a developer would already have knowledge of the written code and will define rules or expectations about how a component should behave (unit tests), or how it should be structured (linting).
Why should you lint your code?
- Pre-code review
- Finding (syntax) errors before execution
As we have the possibility to define a set of styling rules, this increases the readability of our code towards the effort of having our codebase look like it was written by “one person”. This is important, as it can happen that software engineers move from codebase to codebase within projects meaning a lot of people become involved. A common set of rules makes it easier to really understand what the code is doing.
Further linting rules help to improve code reviews, as linting already acts as a pre-code review, checking against all the basic issues such as syntax errors, incorrect naming, the tab vs. spaces debate, etc. It increases the value of having code reviews, as people are then more willing to check the implementation rather than complain about syntax errors.
ESLint in a nutshell
It is also important to note that ESLint doesn’t support new language features until they reach Stage 4 of the proposal process of TC39.
Abstract Syntax Tree
As you can see, the AST of just one line of code and a simple Tree representation contains a lot of information.
What kind of information is in the AST?
Traversing the AST
Estraverse provides a traverse functionality which executes a given statement. In this traverse function we can subscribe to specific types of nodes and complete our analysis. For example, if we want to make sure that all Literal Definitions in our Array declaration are Integers, we could check for that with the sample script below:
Furthermore, the traverse functionality of Estraverse uses the Visitor design pattern, which allows us to execute functions for each visited node of the AST instead of traversing the whole AST and performing operations afterwards. By debugging the traverse function of Estraverse, it has showed that it is using the depth-first algorithm of traversing a Tree. This means Estraverse is traversing to the end of a child node (depth-first) before it begins backtracking. The Visitor pattern, combined with a depth-first search, then allows ESLint to trigger Events whenever it enters an AST node or leaves it immediately.
The architecture of ESLint is pluggable, so if you want to create new rules for specific problems, frameworks, or use cases you have, it is recommended to develop ESLint plugins rather opening up an issue and requesting changes. This presents quite a powerful opportunity to create much more complex code analysis than ESLint can provide. Therefore, developers should consider creating plugins as they are npm modules.
Thanks to the pluggable architecture, it is easy to use already existing plugins or rules for different frameworks, libraries, or companies, e.g. eslint-plugin-react , eslint-plugin-vue or eslint-contrib-airbnb.
As a next step, I’d like to create a small ESLint plugin tutorial for interested developers to see how they can create their own custom ruleset for different use cases, e.g. placing rules into the core of ESLint. If you have any suggestions or ideas for a ESLint plugin you’d like to see, grab me on Twitter at @Fokusman.