Linting
#
We read code more often then we write it: sometimes we spend hours looking for what caused the bug, only to fix it with a single line of code. That’s why consistent code style is important. Ideally code in a project should look like it was written by a single developer. It makes code easier to read because the same formatting patterns are used everywhere in the project.
Why to Lint
#
Good code style can save you from a bug one day. Consider this code:
if (mealType === BREAKFAST)
drinkCoffee();
eatCroissant();
Can you spot the issue? eatCroissant();
gets evaluated with any mealType
value.
Many popular JavaScript code styles require curly braces around all blocks and consistent indentation for this reason. Doing this forces you to write the correct code:
if (mealType === BREAKFAST) {
drinkCoffee();
eatCroissant();
}
You can enforce code style in your project or even autoformat code with linters and code formatting tools. Linting can also capture mistakes in your code before you even run it — thanks to IDE and editor integration.
Code style is subjective and automation can reduce pointless discussions and improve team productivity. It also simplifies switching between different projects and reduces time to ramp up on a new project.
Linting JavaScript With ESLint
#
ESLint↗ is a popular linter for JavaScript. It’s primarily used to capture language related issues but can be used to enforce code style and good practices. It can fix many issues automatically, especially code style. You can write your own rules to ensure code consistency across your team or organization.
JavaScript doesn’t have an official coding style but the community maintains a few. Airbnb↗ and Standard↗ are especially popular: Airbnb is detailed and pragmatic, Standard is a bit controversial because it doesn’t use semicolons. Semistandard↗ is a variant that fixes that issue. These options use two spaces for indentation.
ESLint is unopinionated and doesn’t have any rules by default so you should enable them manually or use a configuration like eslint-config-airbnb-base↗, that implements Airbnb style guide. To get started, use eslint --init
and let it generate a starting point for you.
All ES6 features are supported and babel-eslint↗ adds support for newer ECMAScript features and Flow. ESLint is supported by JetBrains’ IDEs and is available as a plugin for other popular editors.
ESLint itself is modular and uses plugins to operate - for example:
- eslint-plugin-compat↗ checks browser compatibility using Browserslist↗, Can I use↗ and @kangax’s compat↗ table.
- eslint-plugin-import↗ validates ES6 import/export syntax, prevents misspelling of file paths.
- eslint-plugin-react↗ contains best practices for React, JSX code style.
- eslint-plugin-security↗ finds potential security issues in Node code.
Setting up ESLint
#
Let’s install ESLint with the Airbnb config:
npm install eslint eslint-config-airbnb-base eslint-plugin-import --save-dev
Add a new script to your package.json.
{
"scripts": {
"lint:js": "eslint . --fix"
}
}
The --fix
flag tells ESLint to fix problems automatically if it can↗.
Create a config file, .eslintrc.json:
{
"extends": "airbnb-base"
}
And finally run:
npm run lint:js
You may need to tweak your ESLint config according to your project needs:
.eslintrc.json
{
"extends": "airbnb-base",
"parserOptions": {
// ECMAScript version: 3—8 (or 2015—2017), defaults to 5
"ecmaVersion": 6,
// Treat source files as ECMAScript modules, defaults to "script"
"sourceType": "module",
"ecmaFeatures": {
// Enable JSX
"jsx": true,
// Enable object rest/spread properties: {...a, ...b}
"experimentalObjectRestSpread": true
}
},
// If you’re using Flow or experimental ECMAScript features
// not supported by ESLint, enable babel-eslint parser
"parser": "babel-eslint",
// Predefined sets of global variables
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true
}
}
See ESLint docs on configuring↗ for more information.
ESLint Configuration Formats
#
.eslintrc.json supports JavaScript-style comments.
ESLint supports other formats of config files, such as YAML or JavaScript. JSON is a good choice, because other tools can modify such files.
Linting TypeScript With TSLint
#
TSLint↗ is a linter for TypeScript. It has a much smaller community than ESLint and overall experience is not as nice but otherwise it’s like ESLint.
Setting up TSLint
#
Let’s install TSLint with the Airbnb config:
npm install tslint tslint-config-airbnb --save-dev
Update your package.json like this:
{
"scripts": {
"lint:ts": "tslint --fix 'src/**/*.ts'"
}
}
Create a config file, tslint.json:
{
"extends": "tslint-config-airbnb"
}
And finally run:
npm run lint:ts
Linting CSS With Stylelint
#
Stylelint↗ is a CSS linting tool, it’s like ESLint but for CSS. Stylelint understands CSS, including the latest features like custom properties, and SCSS. Sass-like indented syntaxes are supported using PostCSS SugarSS↗. It also has an experimental support for Less.
stylelint-config-standard↗ is a config maintained by stylelint team and follows CSS style guides of GitHub, Google and Airbnb.
Setting up Stylelint
#
Let’s install stylelint:
npm install stylelint stylelint-config-standard --save-dev
Add a script to your package.json like this:
{
"scripts": {
"lint:css": "stylelint --fix '**/*.scss'"
}
}
Create a config file, .stylelintrc:
{
"extends": "stylelint-config-standard"
}
And finally run:
npm run lint:css
Conclusion
#
Code style is an important aspect of code quality and you can enforce code style through tooling. Doing so forces contributors to code using the same standard and this also keeps the source consistent to read. Pushing code style to configuration also avoids arguments about which conventions to apply.
You’ll learn about formatting in the next chapter.