Adding React plugins to ESLint

Let's assume that you want to use the Airbnb set of ESLint rules after having tried it out and liking it. Let's also assume that you want to lint your React component code as well. During the ESLint init process, you've answered No to the question that asks whether or not your project uses React. This time, let's say Yes. So, once again, run the ESLint init process:

npm run lint -- --init

And once again, you want to use the Airbnb lint rules:

? Which style guide do you want to follow? 
  Google 
› Airbnb 
  Standard  

When it asks if you use React, say Yes:

? Do you use React? (y/N) y

You'll notice that a couple of extra packages are installed:

+ [email protected]
+ [email protected]  

Now let's write some React code so that we can lint it. Add the following component to MyComponent.js:

import React, { Component } from 'react'; 
 
class MyComponent extends Component { 
  render() { 
    return ( 
      <section> 
        <h1>My Component</h1> 
      </section> 
    );
  } 
} 
 
export default MyComponent; 

And here is how this component is rendered:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import MyComponent from './MyComponent'; 
 
const root = document.getElementById('root'); 
 
ReactDOM.render( 
  <MyComponent />, 
  root 
); 

You don't need to worry about running this React app in your browser; this is just so that you can make sure that ESLint is able to parse JSX and lint it. Let's try running ESLint now:

npm run lint

Here are the errors this source code generates when linted:

index.js 
  5:14  error  'document' is not defined                      no-undef 
  8:3   error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension 
  9:7   error  Missing trailing comma                         comma-dangle 
 
MyComponent.js 
  3:1  error  Component should be written as a pure function  react/prefer-stateless-function 
  6:7  error  JSX not allowed in files with extension '.js'   react/jsx-filename-extension 

You have errors in both source files to deal with. Let's walk through each of these errors now.

The first error from index.js is no-undef and it's referring to a document identifier that doesn't exist. The thing is, you know that document is an identifier that exists globally in a browser environment. ESLint doesn't know that this global identifier is defined, so we have to tell it about the value in .eslintrc.js:

module.exports = { 
  "extends": "airbnb",
  "globals": {
"document": true } };

In the globals section of the ESLint configuration, you can list the names of global identifiers that ESLint should recognize. The value should be true if the identifier is in fact globally available to source code that references it. This way, ESLint knows not to complain about something that is recognized as a global identifier in a browser environment.

The problem with adding globals for identifiers that exist in a specific environment, like a web browser, is that there are a lot of them. You wouldn't want to have to maintain a list like this just so that ESLint passes your source code. Thankfully, ESLint has a solution for this. Rather than specifying globals, you can specify the environment that your code will be running in:

module.exports = { 
  "extends": "airbnb", 
  "env": { 
    "browser": true 
  } 
}; 

With the browser environment specified as true, ESLint knows about all of the browser globals and will not complain when it finds them in your code. Further, you can specify multiple environments, as it's common to have code that runs both in the browser and in Node.js. Or even if you don't share code between environments, you might want to lint a project that has both client and server code. In either case, here's what multiple ESLint environments:

module.exports = { 
  "extends": "airbnb", 
  "env": { 
    "browser": true, 
    "node": true 
  } 
}; 

The next error to fix is react/jsx-filename-extension. This rule comes from the eslint-plugin-react package that was installed when you initialized your ESLint configuration. The rule expects you to name files that contain JSX syntax using a different extension. Let's assume that you don't want to bother with this (not that I would blame you, that's a lot of effort to maintain two file extensions for almost the same type of file contents). Let's disable this rule for now.

Here's the updated ESLint configuration:

module.exports = {
"extends": "airbnb", "env": { "browser": true, "node": true }, "rules": { "react/jsx-filename-extension": 0 } };

The react/jsx-filename-extension rule is ignored by setting its value to 0 in the rules section of the configuration. Go ahead and run npm run lint again. We're down to two errors now.

The comma-dangle rule is opinionated to be sure, but it's an interesting idea. Let's zoom in on the offending code that triggered this error:

ReactDOM.render( 
  <MyComponent />, 
  root 
); 

ESLint is complaining that there's no trailing comma after the root argument. The idea is that when trailing commas are added:

  • It's easier to add items later on because the comma is already there
  • It leads to cleaner diffs when you commit code because adding or removing items only requires changing one line instead of two

Let's assume that this makes sense and you decide to keep this rule (I like it), here's what the fixed code looks like:

ReactDOM.render( 
  <MyComponent />, 
  root, 
); 

Now let's run npm run lint again. One error left! It's another React-specific error: react/prefer-stateless-function. Let's take another look at your React component that triggered this error:

import React, { Component } from 'react'; 
 
class MyComponent extends Component {

render() { return (
<section> <h1>My Component</h1> </section> ); } } export default MyComponent;

ESLint, with the help of eslint-plugin-react, is telling you that this component should be implemented as a function instead of a class. It says this because it was able to detect that MyComponent doesn't have any state and it doesn't have any life cycle methods. So if it were implemented as a function, it:

  • Would no longer depend on the Component class
  • Would be a simple function with far less syntax than a class
  • Would be obvious that there are no side-effects with this component

With these benefits in mind, let's go ahead and refactor MyComponent into a pure function as the ESLint error suggests:

import React, { Component } from 'react';

const MyComponent = () => (
  <section>
    <h1>My Component</h1>
  </section>
);

export default MyComponent;

And when you run npm run lint, you get:

MyComponent.js 
  1:17  error  'Component' is defined but never used  no-unused-vars 

Woops, you've introduced a new error in the process of fixing another. No big deal, this is why you lint your code, to find things that are easy to miss. In this case, it's the no-unused-vars error because we forgot to take out the Component import. Here's the fixed version:

import React from 'react';
const MyComponent = () => ( <section>
<h1>My Component</h1> </section> ); export default MyComponent;

And you're done, no more errors! With the help of eslint-config-airbnb and eslint-plugin-react, you were able to produce code that any other React developer will have an easy time reading because chances are they're using the exact same code quality standards.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.104.29