How To Set Up ESLint For Modernizing A React App

Make JavaScript code quality better and avoid bugs with the help of a linter and a strict set of rules.

This lesson preview is part of the The newline Guide to Modernizing an Enterprise React App course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to Modernizing an Enterprise React App, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to Modernizing an Enterprise React App
  • [00:00 - 00:10] One of the things developers love and hate the most about JavaScript is the fact that it is a dynamic, loosely typed language. You want to turn that string into an integer?

    [00:11 - 00:13] No problem. That object needs to be an array?

    [00:14 - 00:23] It can do that too. But because JavaScript is so flexible and it lacks a compilation process, it's also especially prone to developer errors.

    [00:24 - 00:30] And we typically find those errors only through code execution. And that's where linters come in.

    [00:31 - 00:38] Linters statically analyze your code to quickly find problems. They can suggest fixes or even fix code automatically sometimes.

    [00:39 - 00:53] And linting tools like ES lint allow developers to discover problems with their JavaScript code without executing it. The bottom line is, linters help make us better developers by alerting us to anti-patterns and bugs before we run our code.

    [00:54 - 01:05] And ES lint is the best linter available today. In this lesson, we'll learn how to add it to our project and set it up to run all the time in our code editor during development.

    [01:06 - 01:17] Fun fact, Create React app already comes with some generic ES lint configurations under the hood. But we're going to take it up a notch and learn how to configure it to our specific project needs.

    [01:18 - 01:27] So what is ES lint exactly? ES lint is the currently preferred linter for JavaScript projects of all sorts.

    [01:28 - 01:43] It's been around since 2013 and its primary reason for being is to allow developers to create their own preferred set of linting rules. ES lint is designed so that all the rules work independently of each other and they can be added and removed or turned on and off at will.

    [01:44 - 01:53] It's very plug and play. Each project use case is unique in some ways and ES lint knows and embraces this, making itself easy to configure to meet the needs of the project.

    [01:54 - 02:14] In addition to being highly configurable, allowing you to add any and all rules you desire, of which there are many, ES lint also integrates very well with lots of code editors, VS code included. So put a pin in that statement for later in the lesson and if you'd like to see some of the available rules for ES lint, just take a look at this link.

    [02:15 - 02:24] These are some of the possible errors that ES lint will look for. There are a lot of opinionated things about ES lint.

    [02:25 - 02:38] So some might argue that ES lint is so un-opinionated when it first starts out that it's not even very useful. And I'm inclined to agree, there's a lot of rules to look through and decide which ones are the standards that your team wants to adhere to.

    [02:39 - 03:04] A fairly common practice that is sprung up today is that projects will use an already defined ES lint config as a starting point and then make tweaks to the originally defined set of rules laid out to suit the team's needs and style of development. One such config that's gained a large and loyal following, especially amongst React development teams, is the ES lint config set forth by the Airbnb team.

    [03:05 - 03:23] It's a robust style guide that's based on standards that are currently prevalent in JavaScript and as the team's docs themselves put it, the config serves as a mostly reasonable approach to react and JSX. Each rule is clearly laid out in the documentation with code examples and some even have extra explanations depending on the rule.

    [03:24 - 03:32] I highly recommend giving it a read. A lot of the rules indirectly spell out React best practices that any code base can benefit from.

    [03:33 - 03:38] But that's enough talk about Airbnb's ES lint config. Let's get started adding it to our project.

    [03:39 - 03:47] And if you'd like to see more, I've linked also to the style guide. The most reasonable approach to JavaScript.

    [03:48 - 04:04] So the first thing you'll want to do is remove any pre-existing ES lint config files that your project may have. It's worth pointing out since this is about modernizing existing React applications that you may already have an ES lint file in your React project.

    [04:05 - 04:19] This file could be something like ES lint RC dot yaml, ES lint RC dot JSON, ES lint RC dot JS, these are all valid ES lint configs. It's flexible in what it will accept, kind of like the prettier RC file.

    [04:20 - 04:30] I would strongly recommend you delete it completely and start fresh. ES lint's made many improvements since that file was probably set up and rules that may previously have been needed are now default.

    [04:31 - 04:34] Configs that existed may have been renamed. You never know.

    [04:35 - 04:50] Instead of trying to merge the existing ES lint file with the new one ID tail below, I would start over. And besides, if you realize that there are some rules that you can't live without, your version control system will remember the old config file and you can grab whatever you need from it.

    [04:51 - 05:02] You are using a version control system, right? Unlike setting up prettier in our previous lesson, which required just one new npm package, ES lint requires a bunch.

    [05:03 - 05:24] If you read the ES lint npm documentation, it outlines all the peer dependencies that the Airbnb ES lint depends on. But instead of just installing whatever the latest version is of each peer depth, it provides a quick shell script to identify the correct version for each additional dependency for the current version of the Airbnb ES lint library.

    [05:25 - 05:33] It's pretty handy. So open up the code in your IDE and cd into your client folder and then run the following commands in the terminal.

    [05:34 - 06:00] npm info, ES lint, config, Airbnb, at latest. And then peer dependencies. So once you run this, you should see all the required peer dependencies for whatever version of the ES lint config Airbnb and PM package we're up to.

    [06:01 - 06:08] It'll look something like this. Depending on which version of ES lint you have, these are the dependencies that will work with it.

    [06:09 - 06:23] Now if you have a version of npm installed that's npm version five or above, there's a little shortcut that you can take to install all these dependencies so you don't have to type them in one by one. So let's check first for your npm version.

    [06:24 - 06:31] Just run npm -v in the terminal. I am up to 6.14.4 so that will work.

    [06:32 - 06:50] And now you can type npx install, your depths -dev, ES lint, config, Airbnb. Yes, we would like to run yarn for our installations.

    [06:51 - 07:00] So type y and let that go. Yes, that command says npx and yes, we're actually using yarn in our project as our package manager.

    [07:01 - 07:14] So npx is smart enough that it can detect that we're using yarn as our package manager and act accordingly. If you're not as familiar with npx, it's a tool that's intended to help round out the experience of using packages from the npm registry.

    [07:15 - 07:34] The same way that npm makes it easy to install and manage dependencies hosted on the registry, npx makes it easy to use CLI tools and other executables that are hosted on the registry. So basically npx makes it possible to install dev dependencies to projects locally without having to install them globally.

    [07:35 - 07:42] It's also great if you just want to try a CLI tool once without having to install it. Just use npx and then whatever the command is.

    [07:43 - 07:57] And when the command isn't already in your path, npx will automatically install a package with that name from the npm registry for you and invoke it. If you'd like to learn more about it, I've actually linked to an article full of useful info about npx.

    [07:58 - 08:06] So if the install was successful, you should see the following sort of output in our terminal afterwards. This looks pretty good to me.

    [08:07 - 08:16] But we're not quite done yet. We have a few more dependencies that we need to install for ESLint to work properly with our Create React app application.

    [08:17 - 08:27] So here are some other dependencies that you need to install. And these are there that's so prettier and the latest version of Create React app will play nice with all of our ESLint rules.

    [08:28 - 08:47] I'll elaborate on this in the troubleshooting section at the end. So once again, in your command line, we're going to do a yarn add to our dev dependencies, the Babel ESLint package, and the ESLint config prettier package.

    [08:48 - 08:56] Go ahead and save those. And then if you check your package JSON in your client folder, you should see the following new dev dependencies.

    [08:57 - 09:10] Now we have some new dev dependencies, Babel ESLint, ESLint, ESLint config, Airbnb, prettier, import, JSX, A11, React, and React hooks. Very good.

    [09:11 - 09:19] So now that we've got all of our ESLint dependencies installed, it's time to actually add our ESLint RC.json file to our project. Now here's a sidebar.

    [09:20 - 09:28] You might be wondering what is the difference between dev dependencies and plain dependencies in a package JSON? Why are they separated?

    [09:29 - 09:40] And the main difference is where the dependencies are required. If your app needs a dependency like React to run in production, then React should be included in the dependencies array.

    [09:41 - 10:00] If an app needs dependencies only during local development and testing, like ESLint, to check your code, then it can be included in the dev dependencies array. Furthermore, any packages listed in the dev dependencies array won't be bundled into your final dist folder at build time when the project goes into production.

    [10:01 - 10:20] While this may seem like a few extra npm packages are small and they won't affect your bundle size too much, anywhere that we can save some space and potentially make load times quicker results in a better user experience. The npm docs, which I've linked to, do a good job of further clarifying how to add and modify packages in a project if you'd like to learn more.

    [10:21 - 10:46] Okay, so it's time to create our eslint RC file and we're going to use NPX once more to generate this file in our project. So to get started, we are going to run the following NPX command, eslint, NPX eslint, dash, dash, in it, and then we're going to follow the prompts in the command line and answer each one to create the file.

    [10:47 - 10:55] Okay, so we want eslint to check syntax and find problems. We are going to be using JavaScript modules.

    [10:56 - 11:00] We're using the React framework. Our project does not use TypeScript.

    [11:01 - 11:14] We're running our code in the browser and we would like our file to be a JSON file. And yes, we would like to install the latest just in case we're not up to date.

    [11:15 - 11:24] After what seems like a very long time, eslint will finally be done doing its installations. So now we should have an eslint RC dot JSON file.

    [11:25 - 11:29] So let's take a look at what we have here. Okay, it's a good starting place.

    [11:30 - 11:47] It's pretty bare bones, but since we're incorporating prettier and Airbnb's esl int configs into the project, we've got some things to add to this file. First, I'm going to show you the final version of the eslint RC dot JSON file within the lesson.

    [11:48 - 11:58] This is the file that I ended up with when I added all of my preferred initial rules, extensions, and plugins. You can go ahead and just copy that and paste it into your own file.

    [11:59 - 12:10] And then if you want to learn more about the various pieces that go into an esl int file, you can read the descriptions. If you'd prefer to just move on to downloading the eslint vs code extension, you can also do that.

    [12:11 - 12:26] I am going to go through each one of the eslint configurations though, but feel free to skip ahead in the lesson if you don't want to. So back over in our browser window, we have our entire eslint JSON file.

    [12:27 - 12:37] So I'm just going to go ahead and copy that and back to vs code, select everything and paste in the new one. Go ahead and give that a save.

    [12:38 - 12:48] And there's quite a bit more to it, but we'll go through each one of these settings now. So if you're to this part of the course, I'm assuming that you'd like to learn more about how eslint works, which is a good thing.

    [12:49 - 13:01] Even though it will still work just fine if you copy paste this into your local project, a better understanding of eslint can only benefit us all in the future. So we'll start at the top of our file and work down section by section.

    [13:02 - 13:11] So the first thing that you'll see is root of true. By default, eslint looks for configuration files in all folders of a project up to the root directory.

    [13:12 - 13:26] While this can be useful if you want all of your projects to follow a certain convention, it can sometimes lead to unexpected results. To limit eslint to a specific project, place root of true inside of your configuration file.

    [13:27 - 13:40] And as soon as eslint finds a config file containing this line, it will stop looking in further parent directories beyond the current one. Env browser true specifies environments and provides predefined global variables, and they're not mutually exclusive.

    [13:41 - 13:49] So you can specify multiple environments within one config file without issue. The ones that we're including in our project should be fairly self-explanatory.

    [13:50 - 13:59] Browser, Jest, ES2021. But if you'd like to see other options of which there are many, you can check out the documentation.

    [14:00 - 14:10] The extends, eslint recommended, prettier, Airbnb, etc. The config file, once extended, can inherit all the traits of another configuration file.

    [14:11 - 14:27] This includes rules, plugins, and language options. So if you look at our extends property, the first two extensions, eslint recommended, and plugin react recommended are automatically included based on how we answered the questions when we created the eslintrc.json file.

    [14:28 - 14:48] The last three extensions of Airbnb, Airbnb hooks, and prettier are from the prettier and Airbnb peer dependencies that we installed in the project manually. The eslint config prettier, in particular, is brought in because otherwise some of eslint's default code formatting rules will conflict with prettier's code formatting rules.

    [14:49 - 14:58] So this turns off those rules that would conflict. And when you're using the extends config, the eslint config prefix can be emitted from the configuration name.

    [14:59 - 15:08] For example, Airbnb inside of the extends resolves as eslint config Airbnb. Onto our plugins.

    [15:09 - 15:21] So a plugin is an NPM package that can add various extensions to eslint. A plugin can perform numerous functions, including but not limited to adding new rules and exporting shareable configurations.

    [15:22 - 15:44] So just make sure the package has been installed in a directory where eslint can require it. This is one reason our eslintrc.json file has to live within our client folder instead of being able to live at the root of our whole application, because it accesses the plugins of React and React hooks, which are installed in the node modules folder at this level.

    [15:45 - 16:01] And just like with the extends property, the plugins property value can emit the eslint plugin prefix of the package name as well. So you might wonder why we're not specifically importing two of the Airbnb peer dependencies in the plugin section of the eslintrc.json file.

    [16:02 - 16:21] And the answer is we don't need to. By extending Airbnb and Airbnb hooks configurations in the file above, the esl int plugin import and the eslint plugin jsxA11y are implicitly included and there's no need to include them explicitly.

    [16:22 - 16:29] Up next is our parser, which is Babel ES lint. So by default, eslint uses a spree as its parser.

    [16:30 - 16:52] ES lint's default parser and core rules, however, only apply the latest final ECMAScript standard and do not support experimental, such as new features and non-standard, such as flow or type script types syntax provided by Babel. Therefore, we use the Babel ES lint parser, a parser that allows eslint to run on source code that is transformed by Babel.

    [16:53 - 17:02] Without specifying this parser, we get some weird errors from the linter without suggestions for how to fix them. I'll show you in the troubleshooting section at the end of this lesson.

    [17:03 - 17:10] Then we move on to parser options. So eslint allows you to specify the JavaScript language options you want to support in your project.

    [17:11 - 17:28] By default, eslint expects ECMAScript 5 syntax. When we answered the questions as the eslint rc.json file was created, eslint overrode that setting to enable support for other ECMAScript versions as well as jsx by using parser options.

    [17:29 - 17:43] As we have a React project, the jsx true was added to the ECMAS feature specification. In addition to ECMAS version 12, support for the latest version of JavaScript and the source type of module since our code is in es modules.

    [17:44 - 17:58] Finally, we come to rules, lots of rules, so many rules for eslint. But thanks to the extensions and the plugins we've added, a lot of the rules that we want are already included for us without our having to define them, which is the best.

    [17:59 - 18:13] The rules are what gives eslint its power and makes it useful to us. I'm not going to go through each rule listed above one by one, but these are ones that I like to change the default configuration for because I don't think they make sense for the projects that I work on.

    [18:14 - 18:25] If you'd like to see exactly what any of the specific rules do, just google esl int whatever rule, react no unused state. And you should get the eslint rule with the definitions and code examples.

    [18:26 - 18:35] It's helpful. If you're curious what automatically enabled rules from the extensions we've added like eslint recommended, it's documented.

    [18:36 - 18:46] All the rules with check marks next to them are automatically turned on. And with that, we've covered all the most important parts of the existing esl int RC.json file.

    [18:47 - 18:57] Now it's time to move on to configuring eslint so that we can identify and fix those errors. And if there's anything else that you wanted to know about eslint that I haven 't covered, I encourage you to check out their documentation.

    [18:58 - 19:14] It's pretty well written. We're going to turn our attention back to our IDE now because just like in the previous prettier lesson, if the s code is your IDE of choice, we're going to make using eslint even more convenient by setting it up to lint files while we're working on them .

    [19:15 - 19:30] Add back over to your IDE and in the extension marketplace, we are going to do another search. Instead of prettier code formatter, we're going to search for eslint.

    [19:31 - 19:36] The very first result that you get is the one authored by dorkboumer. That's the plugin that you want.

    [19:37 - 19:50] Once again, I have installed this, but go ahead and install it now if you haven 't already and restart your instance of vs code so that it takes effect. Then we're going to open up another file within our project to check that esl int has started to work.

    [19:51 - 19:58] So let's take a look at the format filters function. File name is formatfilters.js.

    [19:59 - 20:10] Okay, so it's time to enable eslint in our vs code. Look down at the bottom right of the vs code editor and you should see a little eslint link right here.

    [20:11 - 20:22] Click on it. Terminal should open up showing you the eslint conveges in effect for this project and the eslint link in the bottom of the IDE should have a little check mark next to it if it is.

    [20:23 - 20:29] And it looks like it is. The eslint server is starting, the eslint server is running, telling us where it loaded from.

    [20:30 - 20:41] So if this is the first time that you're enabling eslint in a new vs code project, you may see a modal popping up asking if you'd like to allow eslint to link this project. Hit the allow button.

    [20:42 - 20:47] This lets eslint do its job. So now that we've checked that everything is working, eslint is running.

    [20:48 - 20:57] If you look at the file that we opened, the format filters function, here's what it looks like before we added prettier and eslint to our project. Nothing has happened yet.

    [20:58 - 21:08] I have not auto-saved this and there are already eslint errors starting to pop up. That giant red squiggly that you see where the object to sign code is beginning .

    [21:09 - 21:20] If you've got the vs code problems tab open, you'll see that eslint is telling us to use an object spread instead of object.assign. Now we could fix this issue ourselves.

    [21:21 - 21:22] We definitely could. But guess what?

    [21:23 - 21:28] We don't have to. This is a lending error that eslint is capable of fixing itself.

    [21:29 - 21:39] Want to see it happen? So use the keyboard shortcut of command s on a Mac and control s on a Windows or just save, refocus your code elsewhere.

    [21:40 - 21:47] And like magic, the file looks like this. And if you check the problems tab, the eslint warning is gone.

    [21:48 - 21:53] Eslint fixed that all on its own. How cool is that you guys?

    [21:54 - 21:59] Very cool. vs code combined with eslint is pretty darn amazing.

    [22:00 - 22:18] So while it can't fix every issue, it runs across on its own for whatever files you have open, you can refer to the eslint error either by hovering over the error in the code or referring to it in the problem section of your terminal. And you can see the eslint rule being triggered and suggestions of how to fix the issue.

    [22:19 - 22:30] One thing to note is that the eslint plugin will only identify and fix code for any files that you have open in vs code. So if you close a file, those particular errors will disappear.

    [22:31 - 22:51] The next section that we're going to go through, though, explains how to lint the whole project with just a couple of quick NPM scripts. So regardless of if you're using the vs code plugin to lint files you're actively working on, we need to be able to see the linting errors in all of our files and have eslint fix them for us whenever possible.

    [22:52 - 23:04] So we're going to do this by adding two new scripts in our client folders package JSON. So open up your package JSON and add the following two lines of code at the end of the already existing script section after the eject script.

    [23:05 - 23:24] We're going to add lint and this command will just be eslint src and we're going to add lint fix which is eslint src dash dash fix. So these scripts are one way to check our project for eslint issues and even resolve some of them.

    [23:25 - 23:36] All right, let's talk about these scripts before we get to using them. So the first script which we'd access by running yarn lint is going to identify all of the eslint errors in our project and list them out line by line in the terminal.

    [23:37 - 23:52] So let's see what that looks like. I need to cd into my client folder and then run yarn lint and we see that we have 78 problems and six errors.

    [23:53 - 24:06] So after all the errors have been identified you'll see a print out like this. Notice that the line underneath the initial summary it says six errors and zero warnings potentially fixable with the dash dash fix option.

    [24:07 - 24:12] This is where our second new script comes into play. So the second script is a really cool one.

    [24:13 - 24:25] Every time we run yarn lint fix any linting issues that eslint identifies that it can fix itself it will. So go ahead and run this command and check that out.

    [24:26 - 24:44] Using this command it prints out all the problems that it couldn't fix in addition to a summary at the end showing the new count of issues that are still outstanding. So if we scroll up we see some of the still existing errors but we see that 78 has become 72.

    [24:45 - 24:54] Not too shabby right? So if you check your source control right now you should see a bunch more files in this project that have been updated by this command.

    [24:55 - 25:11] We can fix the rest of the eslint issues that it couldn't resolve in future lessons or you can tackle that on your own as we refactor this application. So let me point out that if you wanted to you could run either of these commands from the command line on the whole project or on a single file.

    [25:12 - 25:32] You just have to do npx and then eslint your source folder and then the folder name the file name or npx eslint your path to your file and then dash dash fix and that 's it. eslint is now fully integrated into our project and it's ready to help us make our code better wherever it can.

    [25:33 - 25:45] Okay so this is the troubleshooting section of this particular lesson. So after all that eslint setup you may have thought that you were done but we 're not quite there yet so hang with me for just a little bit longer.

    [25:46 - 25:55] You may encounter a few common errors when you're adding eslint and I want to equip you to deal with them. Here's the first error you may encounter while setting up eslint in the project .

    [25:56 - 26:21] So do me a favor and inside of your eslint file go ahead and comment out the parser for just a second and then go to your af.js file and now scroll down to our component did mount and check out the little red squiggly that's under the equals sign. We hover over this all we get is parsing error unexpected token eslint.

    [26:22 - 26:24] That is not very helpful. What does that even mean?

    [26:25 - 26:54] It means that the default parser for eslint doesn't recognize the newer syntax that our project is using like arrow functions object destructuring things like this which is why in the required eslint download section I recommended installing the eslint Babel and pm package and we specified it as our parser in our eslint our c.json file. So once it's present and uncommented that weird error it stops happening.

    [26:55 - 27:08] We come back now there's plenty of other things but that little red squiggly is gone. So feel free to re-enable the parser now in your own file just be aware that this may happen if the parser is not set in eslint.

    [27:09 - 27:21] And the other common error that you might encounter after adding eslint is that the app won't start. Try starting the app back up with yarn start in the client folder right now.

    [27:22 - 27:30] Everything seems good at first until we switch over to our newly opened react window. That is absolutely terrifying to me.

    [27:31 - 27:37] I don't know if it is to you too. So this was very alarming to me but do not panic.

    [27:38 - 27:47] For some reason there is a bug. After the react scripts were updated to version 4 some breaking changes happened to the project linting.

    [27:48 - 27:57] It seems that any eslint errors present in the project are not being converted to warnings by default. So instead they're staying as browser errors and causing the app to crash.

    [27:58 - 28:13] The solution however is a new local.env file. So head back into your IDE and we're going to create after I close all of these a new.env file in our client folder.

    [28:14 - 28:30] So create a new file and name it .env and then add the following line to it. eslint no dev errors and set it equal to true.

    [28:31 - 28:43] So with this flag you will receive the eslint errors as warnings in the console and not as errors in the development browser. Now try stopping the app and restarting it in the terminal with the .env file present.

    [28:44 - 29:00] And if you see your browser window now you can breathe a sigh of relief that we are once again a-okay. I hope that this error scenario is fixed when a new version of the react scripts comes out but if you encounter it this is how to fix it.

    [29:01 - 29:20] And this is one of the few times that we don't actually need to add the .env file to our gitignore. It's safe to commit this to github through version control because this file doesn't include any API keys, database connection strings or other sensitive information that we wouldn't want anyone outside of our team knowing.

    [29:21 - 29:24] It's okay to check this one in with project code as it is. So well done.

    [29:25 - 29:31] You made it to the end. I know that this was a longer lesson but getting eslint up and running takes a little bit more doing.

    [29:32 - 29:45] So luckily this is the last lesson for this module and we're done with project configuration for now. In the next module we're going to start refactoring those class-based components to functional components using hooks and I'm excited to get started.