Go to the Centreon Community website

Introduction

This article is for the developers in our community. Centreon’s own developer team is always looking to improve code quality, but above all productivity, so we can all focus on what makes coding interesting: building great apps! Hence the following tutorial, combining two tools we like, ESLint and Prettier, which we use to work better as a team and keep a clean house code-wise.

Let’s start with some basics—if you’re already aware of what code linting is, you can move on to the tutorial on how to enhance teamwork within a React project with ESLint and Prettier.

What is code linting?

Think of the residual stuff in your dryer, lint, which needs to be kept off clean laundry. In programming, a linter refers to a static code analysis tool which is used to keep code error-free and ensure coding style and construction remain coherent no matter the coder.  

As does the greater part of the JavaScript community, we favor the ESLint tool which scans code without having to run it. This highly flexible tool combines a rich plugin library meeting a range of needs and offering the benefit of ready to use configurations. Today, we’re focusing on the Prettier plugin, a tool that allows to automatically reformat code, ensuring consistent rules for indentation, spacing, semicolons, and quotes.

We hope you’ll like this tutorial which tells you how to configure ESLint and the Prettier plugin in a React environment.

Installation and configuration

For this tutorial, we’re going to take the example of a React application. The easiest way to get started is to use create-react-app, so that everything needed to start a React application is bootstrapped for us.

$ npx create-react-app my-app

ESLint is installable as any other npm package. We’re then going to install it using:

$ cd my-app
$ npm install --save-dev eslint

Then, we need to initiate a configuration file in order to tell ESLint what rules to follow when performing its checks:

$ npx eslint --init

The CLI is going to ask a bunch of questions. Answer the following:

How would you like to use ESLint? To check syntax, find problems, and enforce code style
What type of modules does your project use? JavaScript modules (import / export)
Which framework does your project use? React
Does your project use TypeScript? No
Where does your code run? Browser
How would you like to define a style for your project? Use a popular style guide
Which style guide do you want to follow? Airbnb
What format do you want your config file to be in? JavaScript

After answering these questions, the required dependencies are going to be installed on your project. 

Airbnb JavaScript Style Guide has become a solid standard for JavaScript guidelines, and comes up with a well maintained ESLint configuration, which is why we decided to use it as a base for our projects at Centreon, and we suggest you do the same.

Let’s now add a script to your package.json file in order to check the linting problems, as well as one for fixing those that can be fixed:

// package.json

{
  "name": "my-app",
  ...
  },
  "scripts": {
    ...
    "eslint": "eslint src --ext .js,.jsx",
    "eslint:fix": "npm run eslint -- --fix"
  },
  ...
}

Then, let’s check the linting issues we get:

$ npm run eslint

> my-app@0.1.0 eslint
> eslint src --ext .js,.jsx


/Users/brunodauria/my-app/src/App.js
   6:5   error  'React' must be in scope when using JSX                      react/react-in-jsx-scope
   6:5   error  JSX not allowed in files with extension '.js'                react/jsx-filename-extension
   7:7   error  'React' must be in scope when using JSX                      react/react-in-jsx-scope
   8:9   error  'React' must be in scope when using JSX                      react/react-in-jsx-scope
   9:9   error  'React' must be in scope when using JSX                      react/react-in-jsx-scope
  10:16  error  `code` must be placed on a new line                          react/jsx-one-expression-per-line
  10:16  error  'React' must be in scope when using JSX                      react/react-in-jsx-scope
  10:39  error  ` and save to reload.        ` must be placed on a new line  react/jsx-one-expression-per-line
  12:9   error  'React' must be in scope when using JSX                      react/react-in-jsx-scope

/Users/brunodauria/my-app/src/App.test.js
  4:1   error  'test' is not defined                          no-undef
  5:10  error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  5:10  error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension
  7:3   error  'expect' is not defined                        no-undef

/Users/brunodauria/my-app/src/index.js
   8:3   error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension
  11:34  error  Missing trailing comma                         comma-dangle

/Users/brunodauria/my-app/src/reportWebVitals.js
  1:25  error  Expected parentheses around arrow function argument  arrow-parens
  3:32  error  Expected a line break after this opening brace       object-curly-newline
  3:74  error  Expected a line break before this closing brace      object-curly-newline

18 problems (18 errors, 0 warnings)
  6 errors and 0 warnings potentially fixable with the `--fix` option.

First things first, let’s tackle the low hanging fruits by automatically fixing some errors:

$ npm run eslint:fix

> my-app@0.1.0 eslint:fix
> npm run eslint -- --fix


> my-app@0.1.0 eslint
> eslint src "--fix"


/Users/brunodauria/my-app/src/App.js
   6:5   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   6:5   error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension
   7:7   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   8:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   9:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  12:11  error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  16:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope

/Users/brunodauria/my-app/src/App.test.js
  4:1   error  'test' is not defined                          no-undef
  5:10  error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  5:10  error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension
  7:3   error  'expect' is not defined                        no-undef

/Users/brunodauria/my-app/src/index.js
  8:3  error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension

12 problems (12 errors, 0 warnings)

We can see a bunch of errors indicating that React must be in scope within JSX files. Since in React v17 this is no longer required, we’ll disable that rule in the .eslintrc.js file:

module.exports = {
  ...
  rules: {
    'react/react-in-jsx-scope': 'off',
  },
};

Let’s rename the files containing JSX using the .jsx extension:

$ mv src/App.js src/App.jsx
$ mv src/index.js src/index.jsx
$ mv src/index.test.js src/index.test.jsx

We’re now left with two errors:

$ npm run eslint 

> my-app@0.1.0 eslint
> eslint src --ext .js,.jsx


/Users/brunodauria/my-app/src/App.test.jsx
  4:1  error  'test' is not defined    no-undef
  7:3  error  'expect' is not defined  no-undef

2 problems (2 errors, 0 warnings)

Since they are directly linked to the way Jest works (JavaScript testing framework), we can either disable them within the test files (ending with .test.js or .test.jsx), or add a dedicated ESLint plugin. We’re going to do the latter as it will prevent us from writing code that potentially won’t be caught by our linter.

Let’s install the plugin:

$ npm install --save-dev eslint-plugin-jest

Then, add the plugin to the eslint configuration:

// .eslintrc.js

module.exports = {
  env: {
    ...
    'jest/globals': true,
  },
  ...
  plugins: [
    ...
    'jest',
  ],
  ...
};

Which should let us free from linting issues.

Adding formatting rules using the Prettier plugin

Formatting the code automatically to make it clear and readable is crucial when working in a team (and helps tremendously when working alone as well). It can save a lot of time, particularly when reviewing diffs coming from a PR, and make you focus on the actual code you write instead of trying to arrange it esthetically. 

Prettier does this for you, with minimal configuration, and in an opinionated way so that you don’t have to worry about too many rules. Luckily for us, it has an ESLint plugin, so that it’s completely integrated, avoiding the use of different tools. Any formatting violation becomes a linting issue and gets caught when ESLint runs. 

First off, we need to tell ESLint which rules need to be disabled in order to avoid conflicts with Prettier. This is done by the package eslint-config-prettier. Let’s install it:

$ npm install --save-dev eslint-config-prettier

Then, add it to the eslint config file: 

// .eslintrc.js

module.exports = {
  ...
  extends: [
    ...
    'prettier',
  ],
  ...
};

Now, we’re going to install the plugin to integrate Prettier with our ESlint rules:

$ npm install --save-dev eslint-plugin-prettier

Then, add the plugin to the ESLint config file, as well as the corresponding rule:

//.eslintrc.js

module.exports = {
  ...
  plugins: [
    ...
    'prettier'
  ],
  ...
  rules: {
    ...
    "prettier/prettier": "error",
  },
};

Now, let’s check the ESLint output:

$ npm run eslint

> my-app@0.1.0 eslint
> eslint src --ext .js,.jsx


/Users/brunodauria/my-app/src/App.jsx
   1:18  error  Replace `'./logo.svg'` with `"./logo.svg"`                                                                                prettier/prettier
   2:8   error  Replace `'./App.css'` with `"./App.css"`                                                                                  prettier/prettier
  10:15  error  Replace `⏎··········{'·'}⏎··········<code>src/App.jsx</code>⏎··········{'·'}⏎·········` with `·<code>src/App.jsx</code>`  prettier/prettier

/Users/brunodauria/my-app/src/App.test.jsx
  1:32  error  Replace `'@testing-library/react'` with `"@testing-library/react"`      prettier/prettier
  2:17  error  Replace `'./App'` with `"./App"`                                        prettier/prettier
  4:6   error  Replace `'renders·learn·react·link'` with `"renders·learn·react·link"`  prettier/prettier

/Users/brunodauria/my-app/src/index.jsx
   1:19  error  Replace `'react'` with `"react"`                          prettier/prettier
   2:22  error  Replace `'react-dom'` with `"react-dom"`                  prettier/prettier
   3:8   error  Replace `'./index.css'` with `"./index.css"`              prettier/prettier
   4:17  error  Replace `'./App'` with `"./App"`                          prettier/prettier
   5:29  error  Replace `'./reportWebVitals'` with `"./reportWebVitals"`  prettier/prettier
  11:27  error  Replace `'root'),` with `"root")`                         prettier/prettier

/Users/brunodauria/my-app/src/reportWebVitals.js
  3:12  error  Replace `'web-vitals').then(({⏎······getCLS,·getFID,·getFCP,·getLCP,·getTTFB,⏎···` with `"web-vitals").then(({·getCLS,·getFID,·getFCP,·getLCP,·getTTFB`  prettier/prettier

/Users/brunodauria/my-app/src/setupTests.js
  5:8  error  Replace `'@testing-library/jest-dom'` with `"@testing-library/jest-dom"`  prettier/prettier

14 problems (14 errors, 0 warnings)
  14 errors and 0 warnings potentially fixable with the `--fix` option.

The good thing is that the vast majority of Prettier errors can be fixed automatically. To fix the ones reported above, we just need to run:

$ npm run eslint:fix

Which should now set us free of issues.

We’re going to see in the next section that there is a way to catch all these issues even faster, directly within VSCode, if that’s the editor you’re using, and if not, it might be the time to do so :).

Configure ESLint within VSCode

One of the great things about VSCode is the impressive amount of extensions available. ESLint is one of them and it helps shorten the feedback loop of the linting process. To install it, open up the extension manager, search for ESLint and install it:

Then, you need to allow the extension to check the files by clicking on the ESlint button inside the task bar at the bottom of the screen. When this is done, you should have a double check icon appearing beside it:

Then, in order to indicate which source types need to be validated by ESLint when coding, you need to add the following parameter to your settings.json file (Files > Preferences > Settings):

...
    "eslint.validate": [
        "javascript",
        "javascriptreact"
    ]

Finally, to automatically fix the resulting issues when saving a file, add the following parameter:

...
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    }

Now, in addition to having the linting issues (including the formatting ones coming from Prettier), saving a file will also fix all the fixable issues:

And we’re all setup! 

If you have any questions or comments, ask on The Watch.


Bruno D'Auria, Team Leader - Modern UX/UI

An IMT Atlantique graduate, Bruno holds a master’s degree in computer science, networks, and telecommunications. Bruno worked as a software developer in a wide range of industries: telecommunications, sports, energy, real estate, and home automation before his decision to specialize in web and mobile interface development. Bruno joined Centreon in 2018, leading today the Modern UI/UX team. Bruno’s mission is to design and implement next-generation interfaces for always more intuitive, enjoyable user experiences.