Improve Your Code Quality with ESLint: Best Practices and Common Errors

Learn how to leverage ESLint, a powerful tool for linting JavaScript and TypeScript code. From understanding different types of rules, setting up plugins, dealing with common errors to creating custom rules and ignoring files

· 6 min read
Improve Your Code Quality with ESLint: Best Practices and Common Errors

ESLint is an open-source JavaScript linting utility. Linting is a process that runs a program that will analyze code for potential errors. ESLint helps in finding and reporting errors in JavaScript code, making the code more reliable and bugs less likely to occur. ESLint is written in Node.js, making it a great tool for JavaScript developers as JavaScript does not have a compilation step. ESLint is also pluggable, meaning every single rule is a plugin and you can add more at runtime. It is built into most text editors and can be run as part of your continuous integration pipeline eslint.org.

How to Install ESLint


To install ESLint, you can use npm (node package manager). Run the following command to install ESLint globally:

npm install -g eslint

After installing ESLint, you can create a .eslintrc configuration file by running:

eslint --init

This command will initiate a process that will determine the best configuration for your project based on your answers to several questions. To run ESLint against any file, use:

eslint yourfile.js

Using ESLint in Your Editor

You can integrate ESLint into your favorite editor. Most modern IDEs (like IntelliJ, VS Code, Atom etc.) support ESLint. After installing ESLint, you will notice colorful underlining in your files highlighting errors. These markers are color-coded based on severity, helping you find and remove code and syntax errors.

Configuring ESLint

The ESLint configuration file is called .eslintrc. It's where you define the rules you want to apply to your code. This file can be either in JSON or YAML format.

Here is a simple example of an .eslintrc file:

{
  "plugins": [
    "@typescript-eslint",
    "prettier",
    "unicorn" ,
    "import"
  ],
  "extends": [
    "airbnb-typescript/base",
    "plugin:@typescript-eslint/recommended",
    "plugin:unicorn/recommended",
    "plugin:prettier/recommended",
    "prettier",
    "prettier/@typescript-eslint"
  ],
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true
  },
  "rules": {
    "no-debugger": "off",
    "no-console": 0
  }
}

In this configuration file:

plugins: is an array of plugins that ESLint should use.

  • extends: is an array of configurations that ESLint extends. A config is a prepackaged set of rules, parser settings, and environment settings that ESLint should use.
  • parserOptions: is an object that sets parser options. Parser options can be things like the ECMAScript version to use.
  • env: is an object that defines global variables that are predefined.
  • rules: is an object where you can override settings specified in the configs that you are extending, or define new ones.


Now that we've covered the basics of ESLint, let's delve further into its advanced usage and configuration. This includes understanding different types of rules, setting up plugins, and dealing with common errors.

Types of ESLint Rules

ESLint has three types of rules:

  1. Possible Errors: These rules relate to syntax errors or logic errors in JavaScript code. For example, no-extra-semi rule disallows unnecessary semicolons.
  2. Best Practices: These rules ensure that you are using the features of JavaScript in the most optimal way. For instance, no-eval rule warns against the use of eval() function as it is potentially dangerous.
  3. Stylistic Issues: These rules enforce a consistent style across your codebase. An example is indent rule which enforces consistent indentation levels.

You can specify the severity of each rule in your .eslintrc file with "off", "warn", or "error" values.

ESLint Rules

In ESLint, rules are the core scripts that analyze your code for potential issues. Each rule has a unique name and corresponds to a specific aspect of the code.

You can set the severity of each rule to one of the following values in your ESLint configuration file:

  • "off" or 0 - turn the rule off
  • "warn" or 1 - turn the rule on as a warning (doesn't affect exit code)
  • "error" or 2 - turn the rule on as an error (exit code will be 1)

For example:

{
  "rules": {
    "eqeqeq": "error",
    "curly": "warn",
    "quotes": ["error", "double"],
    "semi": ["error", "always"]
  }
}

In this configuration, the eqeqeq rule is set to "error", the curly rule is set to "warn", and the quotes and semi rules are set to "error" with additional configuration options.

Custom ESLint Rules

One of the powerful features of ESLint is that you can write your own rules. This allows you to enforce specific coding standards or practices that are not covered by existing rules or plugins.

To write a custom rule, you need to create a JavaScript file that exports a plain object with several properties, including meta and create. The meta property provides information about the rule, and the create property is a function that returns an object containing methods that define the rule's behavior.

Here's an example of a simple custom rule that disallows the use of console.log():

module.exports = {
  meta: {
    type: "problem",
    docs: {
      description: "disallow the use of console.log()",
      category: "Possible Errors",
      recommended: true,
    },
    fixable: "code",
  },

  create: function(context) {
    return {
      CallExpression(node) {
        if (
          node.callee.type === "MemberExpression" &&
          node.callee.object.name === "console" &&
          node.callee.property.name === "log"
        ) {
          context.report({
            node,
            message: "Unexpected console.log",
          });
        }
      },
    };
  },
};

This rule can be added to your ESLint configuration by including the path to the rule file with the rules property.


Setting Up ESLint Plugins

ESLint plugins allow you to define your own rules, use a set of predefined rules, or modify the behavior of existing rules. To use a plugin, you need to install it using npm and then reference it in your ESLint configuration file.

For example, to install and use the React plugin for ESLint, you would run:

npm install eslint-plugin-react

Then add it to your ESLint configuration:

{
  "plugins": [
    "react"
  ]
}


You can then enable or configure the rules provided by the plugin in the rules section of your configuration file.


Common ESLint Errors

While using ESLint, you might encounter some common errors. Here are a few examples and how to resolve them:

  • Parsing error: Unexpected token: This error occurs when ESLint encounters a piece of syntax it doesn't recognize. This often happens when you're using a feature of JavaScript that ESLint's default parser doesn't support (like JSX or types from TypeScript). To fix this, you can switch to a parser that supports the syntax you're using, such as Babel-ESLint for Babel code or @typescript-eslint/parser for TypeScript code.
  • 'X' is assigned a value but never used: This warning is shown when a variable is declared or assigned a value, but not used anywhere. To resolve this, either use the variable or remove the declaration.
  • 'X' is not defined: This error is displayed when a variable is used but not declared in the scope. To fix this, declare the variable or if it's a global variable, add it to the globals section in your ESLint configuration file.

In conclusion, ESLint is a highly flexible and configurable tool that can significantly improve your JavaScript code quality. By understanding its advanced usage and configuration, you can customize ESLint to suit your project's unique requirements.


Ignoring Files and Directories

In some cases, you might not want ESLint to lint some files or directories in your project. ESLint provides two ways to ignore files - .eslintignore file or ignorePatterns in your configuration file.

.eslintignore


You can create a .eslintignore file in the same directory as your .eslintrc file. This file should contain patterns that match the files and directories you want to ignore. The patterns should follow the .gitignore syntax. Here's an example:

node_modules/*
dist/*

This will ignore all files in the node_modules and dist directories.

ignorePatterns in Configuration File


Alternatively, you can specify ignorePatterns in your configuration file. The value of ignorePatterns should be an array of strings where each string is a pattern that matches the files and directories you want to ignore.

{
  "ignorePatterns": ["node_modules/", "dist/"],
  "rules": {
    // ...
  }
}

This does the same as the .eslintignore file above.


ESLint with TypeScript

If you're using TypeScript, you'll want to use ESLint to lint your TypeScript code. To do this, you'll need to install the @typescript-eslint/parser and @typescript-eslint/eslint-plugin packages.

npm install @typescript-eslint/parser @typescript-eslint/eslint-plugin

Then, in your .eslintrc file, specify @typescript-eslint/parser as your parser and include @typescript-eslint in your plugins:

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "rules": {
    // ...
  }
}

Now ESLint will be able to lint your TypeScript code.

ESLint with Prettier


You can also use ESLint along with Prettier, a code formatter. This allows you to use ESLint for code quality and Prettier for formatting. To do this, you'll need to install eslint-plugin-prettier and eslint-config-prettier.

npm install eslint-plugin-prettier eslint-config-prettier

Then, in your .eslintrc file, extend prettier and add prettier to your plugins:

{
  "extends": ["prettier"],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}

With this setup, any time you run ESLint, it will also run Prettier as a rule and report any formatting errors.

That's all!! we reached the end of our tutorial. We covered the most important technical details of Eslint exploring its power and flexibility with JavaScript and TypeScript code.