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.
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.
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:
Let’s install ESLint with the Airbnb config:
npm install eslint eslint-config-airbnb-base eslint-plugin-import --save-dev
eslint-plugin-import is a peer dependency of eslint-config-airbnb-base, you need to install it to use the Airbnb preset.
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.
To get most value out of linting tools during development, make sure you have installed editor plugins. This way you can get feedback realtime as you develop and can spot potential issues earlier.
The _Customizing ESLint_ appendix discusses how to get more out of ESLint.
[Use Mrm](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-eslint) to add ESLint to your project with a single command.
.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.
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.
[TypeScript support](https://github.com/eslint/typescript-eslint-parser) for ESLint is experimental and has known issues.
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
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.
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
[Use Mrm](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-stylelint) to add stylelint to your project with a single command.
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.
See the _Automation_ chapter to learn how to automate linting.
This book is available through Leanpub. By purchasing the book you support the development of further content.