1. 27
    Avoid Common JavaScript Errors with ESLint
    8m 59s

Avoid Common JavaScript Errors with ESLint

Andy Van Slaars
InstructorAndy Van Slaars
Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 5 years ago

JavaScript is great! JavaScript is also full of features and flexible options that can make it easy to introduce bugs. ESLint uses static analysis to check that your code adheres to a list of rules to help you avoid some specific runtime errors. ESLint is highly configurable, so in this lesson, we'll install ESLint and configure some baseline rules for our boilerplate.

Instructor: [00:00] Let's add ESLint to this project to help us avoid some common JavaScript errors. We'll start with an npm i -d to save this as a dev dependency, and we're going to install ESLint. Because this project uses React, we're also going to install ESLint plugin React.

[00:20] With that installed let's open up our package.json. In our script section, we're going to add a script we'll call lint. The body of the script is going to be a call to ESLint. We're going to have it basically just have it lint all of our JavaScript files.

[00:38] I'll save that. Now, in the terminal, I'm going to run that script with npm run lint, and we're going to get this error that ESLint couldn't find a configuration file. We can set that up with this ESLint init command.

[00:53] Let's clear out our terminal and we're going to use NPX to do this, npx eslint. We'll pass it that init flag. We're going to get a series of prompts, and let's walk through those now. We can pick between using a popular style guide, answering questions about our style, or inspecting our JavaScript files.

[01:11] We're going to go with the answer questions about your style option. It's going to ask which version of that kind of ECMAScript we use. We're going to go down to ES2018. Are we using ES6 modules? The answer to that is yes. Where will you code run? The answer to this is actually both, because we also want to lint things like our webpack config files.

[01:32] I'm going to use A to toggle both browser and Node on. Because we're using both browser and Node, we do use common JS, JSX, and React. Our style of indentation is spaces. We use single quotes. Unix line endings, semicolons, we'll say no, and the format for our config file can just be JSON. It's going to create this ESLintRc.json file.

[01:59] It's also going to tell us that we have a dependency, this eslint-plugin-react, which we installed along with ESLint, so that's handled. We can get rid of this, and in our ESLint RC, we'll see that it's created this config file with quite a few options. At the top of this file, we have this ENV key, and that defines the environments that our code can run in.

[02:21] As you'll see, we have multiple environments. Some of our code is Node-based. Some is meant for the browser. This is going to make sure that things like the window global in our browser code doesn't throw an error, because it's not defined somewhere. This environment's going to say that window is an acceptable global to use.

[02:38] Then we have the extends key. This allows us to extend existing configurations. ESLint comes with this built-in recommended configuration that we're going to extend here, and we'll come back to this in a second. Parser options configures things like support for JSX and our ES version. 

[02:56] You'll see that we have this React plugin, so this is going to apply some React-specific configuration. Then we have the rules section. When we look at the rules, you're going to see things like indent, line break style, quotes, and semicolons. 

[03:10] These are all formatting-related, and since this project is already configured with Prettier, we're not going to enforce those rules through ESLint, we're just going to let Prettier automatically format our code. For this configuration, we can actually delete this entire rules section.

[03:24] If I get that terminal out of the way, I can come up here, and I can delete the rules key, and the entire object value. We'll save that. If we jump back up, we can go back to this extends. Part of what this recommended ESLint config does is it includes certain rules that are recommended.

[03:44] If we look at the ESLint website, there's a long list of rules. They're broken out into categories, things like possible errors, best practices, etc. If we scroll down, any rule that has a checkbox in this column to the left here is part of that recommended set of rules.

[04:00] As we can see as we scroll through here, there's a lot of rules that are included out of the box, when we extend that recommended config. Rather than defining a bunch of specific rules, we're going to stick with the recommended ones.

[04:13] Let's go back to the code, and in our terminal, let's run that lint command again, now that we have our configuration file in place. I'm going to npm run lint, and we're going to get another failure. Let's expand this, and let's take a look. We'll see that we have a lot of problems.

[04:32] We're going to see a lot of errors related to this unnecessary semicolon rule. If we look, we'll see that this is actually coming from our app bundle code in our dist directory. This is generated code. We don't really want to lint this. In the root of our project, I'm going to go in and I'm going to add an ESLint ignore file.

[04:51] In that file, I'm going to add the dist directory as an ignore. I'll save that file, and then back in the terminal, let's run this again. We're still going to get errors, but you'll see we went from 45 problems down to 4. This is progress. Let's scroll up, and you'll see that we're getting a parsing error for this unexpected token import.

[05:12] To fix this, I'm going to actually install another package. I'm going to npm i -d and I'm going to install babel-eslint. With that installed, I'm going to go into my ESLintRc.json file and right at the top, I'm going to add another key to this file. I'm going to come in here, and I'm going to add a parser key. My parser is going to be babel-eslint.

[05:39] I'll go back into the terminal, and I'm going to run npm run lint one more time. Now, we've gone from four problems to eight problems, so it seems to be getting worse, but if we look at the errors, we'll see that it's no longer complaining about our syntax. Now, it's complaining about specific errors related to React and some globals that we're using.

[05:59] We can clean these up with some more configuration. I'll get the terminal out of the way, and I'm going to go into this extend setting here. I'm going to make this an array of strings, and my second element in this array here is going to be our React-recommended rules from our plugin. 

[06:17] We're going to prefix this with plugin, and that plugin is React. From that, we want to use the recommended settings. We can save that, and let's go back into our terminal, npm run lint, again. Now, we're down to three issues. Let's start with this component definition is missing display name issue. 

[06:41] This is coming from our React plugin, and this is coming from warning.js. Let's get the terminal out of the way. I'm going to go into warning.js, and here, we're exporting a default function component. I'm going to take the exportDefault, cut that. I'm going to define a constant called warning, and I'm going to assign that function component to warning.

[07:00] I'm going to drop down, I'm going to export defaultWarning. We still have the same behavior we had before, but now we can access this function by name. I'm going to come in here, I'm going to set warning.displayName, and I'm going to give that a display name of warning.

[07:20] I can close that file, and back in my terminal, I can npm run lint one more time. That error has been cleared up, and we're down to two problems. Both of these problems are in our app.spec.js, and ESLint doesn't like the fact that we're using describe init, without having them defined. 

[07:37] We're not importing them, so if we look at our file here, we'll see that describe init are just globals Those are defined by Jest, and this is a legitimate use for these globals, we just need to let ESLint know. We'll come in here, and in our ESLint.json, we're going to add another environment for Jest.

[07:59] We'll just add a Jest key, with the value of true, we'll save that, and then back in the terminal, we can npm run lint, and everything passes. We're not breaking any rules, but we do still have this warning left over. I'd like to clear that up. This is saying that the React version's not specified, and the eslint-plugin-react wants to see that.

[08:18] Let's get the terminal out of the way. In our ESLint config, we're going to add a settings key at our top level, and that's going to be an object. That object is going to get a React key, which will also be an object. That's going to get a version, and that's going to get our version number as a string.

[08:39] Let's double check in our package.json. We can look at our dependencies, and we'll see that we're using React 16.6.1. I'm just going to copy that and paste it right into that config. I'll save it, come back in the terminal. I'll run npm lint one more time, and now that warning's gone away, and we're not breaking any rules.

Hrafnkell Pálsson
Hrafnkell Pálsson
~ 5 years ago

You can also use "settings": { "react": { "version": "detect", }, }

Hrafnkell Pálsson
Hrafnkell Pálsson
~ 5 years ago

You can also use "settings": { "react": { "version": "detect", } }

Hrafnkell Pálsson
Hrafnkell Pálsson
~ 5 years ago

Ok, final try to get rid of extra commas 😂 "settings": { "react": { "version": "detect" } }

Andy Van Slaars
Andy Van Slaarsinstructor
~ 5 years ago

Hrafnkell, that’s a great tip! Thanks for sharing!

2359 Media
2359 Media
~ 5 years ago

Hello Andy,

May I ask what is the purpose of this -> Warning.displayName = 'Warning' ?

Thanks

Hakan Karaduman
Hakan Karaduman
~ 5 years ago

Thanks so much for this lesson, so helpful.

Kamil L
Kamil L
~ 5 years ago

Property displayName it's not needed because it's automatically set up to component name. It is only needed if you want display different name for debugging purposes. https://reactjs.org/docs/react-component.html#displayname

Andy Van Slaars
Andy Van Slaarsinstructor
~ 5 years ago

right, displayName is not strictly required. We’re applying it here to adhere to a lint rule that enforces some standard practices across a code base. Display name is derived from the component, but it’s useful to explicitly set one when using higher order components to create a new component. The displayName shows up in error messages and in the DevTools. Ultimately, if you don’t find this useful in your code, you can disable the lint rule.

Markdown supported.
Become a member to join the discussionEnroll Today