If you’ve worked with React, you’ve probably seen more than one warning or error in the browser console. Some of them are the effect of ESLint. It’s integrated with the application that we create using the CRA. However, it has a very minimalist configuration there.
Default ESLint config in the package.json file for a React.js application created with the CRA
However, if for some reason you do not have ESLint in your project, you can easily add it using the command npm install eslint --save-dev.
To make the linter a real “lifesaver” of our project, we need to extend this basic configuration a bit. By default, it only has a set of React-specific core rules and doesn’t check the JS syntax itself.
I suggest starting with the configuration recommended by the ESLint team: "eslint:recommended".
The exact contents of this set can be seen here.
The linter configuration can be extended in two ways:
Both work equally well, but as a fan of breaking everything down into as many little chunks as possible, I recommend separating the config into a new file. Divide and conquer!
Remember, however, that when you create the configuration in a separate file, you should remove the eslintConfig from package.json.
The .eslintrc configuration file consists of several sections:
Our basic configuration should look something like this:
Note: it’s very important that "react-app" and "react-app/jest" remain in "extends" of our project (because they “check” React mechanisms)!
This is a good starting point for neat and conscious use of your linter. However, you can change this configuration (using the official documentation) or simply make your own rule modifications (which are also well documented in the ESLint documentation).
Certainly not immediately. I’d suggest starting with the recommended set of rules and introducing any changes only when one is missing or one of them contradicts the requirements of your project.
Of course, don’t forget to discuss it thoroughly within the team so that all of its members are unanimous and understand why this rule has been changed.
To add your own rule or change how the existing rule works, we first need to find it in the rule set.
Then we can add it to the config rules section (if we want it to apply to the entire project) or to the overrides section (if it’s supposed to work only with a certain group of files) with one of the three expected values given below, which will determine how the linter will respond to the code fragments falling under it:
For example: "no-console": "error" will block application compilation (it will throw an error) as soon as the linter detects console.log.
A sample configuration extended by the "no-console" rule
In our project, the linter can be run in several ways.
As soon as you restart the application, the new configuration should be taken into account and the linter will check the code according to it every time you compile it.
Of course, we can also analyze the entire project ourselves. There are several ways to do this.
The easiest one is to add the appropriate script to the package.json file, then run it with the nam run lint command.
You may also use the npx tool:
As you may have noticed, I added the –fix flag to the ESLint command. Thanks to it, the linter will automatically repair some of the errors it encounters, which will further improve the entire process.
Another thing to ensure in your project is that your code is automatically formatted according to a centralized configuration. Usually, each developer on the team has slightly different preferences, which is totally fine, though it can lead to minor or major problems.
By the way, Prettier was created as a way to stop all discussions about which formatting is better. Its formatting style is a result of long debates, as it’s meant to be a compromise between the requirements of all developers.
One of these problems will surely be confusion in pull/merge requests. Suddenly, it may turn out that we have “modified” many more lines of code than was originally intended to result from the changes related to the new functionality or fixes. It’s only our formatter that ordered the code “in its own way.”
Of course, this doesn’t change the functionality of the application, but it does introduce unnecessary confusion. It won’t be immediately clear to the person conducting the code review which parts of the code they need to check.
To introduce standardized code formatting at the project level, we will use Prettier.
So let’s move on to its installation itself. Unlike ESlint, this tool is not built into the CRA, but as is the case with all NPM packages, the installation is very simple and limited to the following command:
Then we’ll configure our formatter. To do this, we will use two files: .prettierrc.json that contains the configuration and .prettierignore where we can list files and folders that Prettier should skip (this file works in the same way as .gitignore).
Sample .prettierrc.json configuration
Sample .prettierignore configuration for React
If you’re adding Prettier to an existing project, note that the first time you use it, it will likely format most of the files in the project. Therefore, it’s a good idea to do it right away, in a dedicated commit.
Just remember to notify the whole team about the need to download the latest version of the code. Otherwise, you will face clashes between the code with the new configuration and the out-of-date versions of the project.
Like with the linter, we can start Prettier in two ways:
We also need to adjust the ESLint configuration by adding the information that we’ll also be using Prettier in the project. Otherwise, the two systems may clash.
To do this, you must first install the Prettier-specific ESLint config with the command:
Then you add it to the “extends” section in the .eslintrc file. It’s really important to add it as the last item, since it has to override a few entries from the previous set of rules.
Finally, let’s automate running both of these tools to improve our workflow. We’ll use Husky for that. It’s a tool that enables integration with Git hooks… so little, and yet so much!
Git hooks are a way to run any scripts in response to various actions related to the Git version control system.
To make it as simple as possible, we’ll use the lint-staged project, which will streamline this process and introduce one more important optimization.
While reading the paragraphs on ESlint and Prettier, you may have started to wonder whether such a solution would slow down your project. After all, continuous formatting and analyzing several hundred—or even several thousand!—lines of code in several files can definitely take a long time, which can be irritating with each commit.
Moreover, it’s easy to see that most of these files won’t even be modified, so it will be a waste of time to constantly analyze them.
Fortunately, there is a way for that: the lint-staged tool. It allows for a fabulously simple integration with the Git hook pre-commit, which is quite enough to start with.
We install it in a slightly different way than the rest. This time, we’ll use the following command:
To read more on how exactly this tool works, I encourage you to browse the GitHub page of the project.
This command—or actually the script we run with it—does a few things that are important to us:
After installing lint-staged, we need to add the configuration of this tool to package.json. It consists of JSON, which takes the name of a file (or a regex that defines a group of files) as a key. What it takes as a value is a string with a command to be executed or an array of strings if there are several such commands.
If you created your application via the CRA, it’s most likely that lint-staged only configured Prettier for you. Therefore, we’ll add the linter to the lint-staged configuration, as in the example below.
A dozen or so minutes devoted to the configuration we’ve presented above will save you a lot of stress and countless hours that you’d spend debugging a problem that could be caught by the linter at the stage of writing the code.
Add to that all the time you’d spend analyzing Git changes, resulting only from the differences in the formatter configuration of the IDE among individual developers on the team—changes that don’t affect the functionality of the application, and are merely code formatting.
In addition, your code will simply be nicer and in line with good practices, which will definitely make it easier to work with.
As you may have guessed, what I’ve discussed in this article is just the tip of the iceberg, especially in the context of ESLint itself and the possibilities this tool offers. Here are some interesting links that will allow you to broaden your knowledge on this topic:
Plus the pages of the tools used here:
Thanks for reading our article on protecting your project against accidental mistakes by using ESLint, Prettier, and Husky. It should save you a lot of trouble in the future.
We have several other technical guides written by experts on a variety of subjects that’ll help you overcome multiple development challenges. Here are some examples: