JavaScript linting with ESLint

Aug 3, 2024 by Thibault Debatty | 343 views

JavaScript

https://cylab.be/blog/354/javascript-linting-with-eslint

JavaScript has become the real backbone of modern web development. As of 2023, JavaScript continues to dominate as the most popular programming language, with over 65% of developers using it regularly, according to the Stack Overflow Developer Survey.

However, the dynamic nature of JavaScript, while offering flexibility, can lead to code that’s difficult to debug and maintain. In large codebases or collaborative projects, inconsistent coding styles and overlooked errors can significantly hinder productivity and code quality. This is where ESLint steps in.

ESLint is a widely-used static code analysis tool designed to identify and report on patterns found in ECMAScript/JavaScript code. By leveraging ESLint, developers can catch common mistakes, enforce coding conventions, and ensure that their codebase remains clean and maintainable. Whether you are working on a personal project or collaborating with a large team, ESLint can be an invaluable addition to your development workflow.

In this blog post, we’ll show how to quickly get started with ESLint…

Prerequisite : node

To install and run ESLint, you will need a recent version of node, npm and npx. At the time of writing, the latest LTS release is 18.18.0.

In the example below, I will use a Laravel project, and I use docker-compose to create a development environment. So I will show the commands for both host-based npm and docker-compose. For the reference, my docker-compose.yaml looks like this:

#
# docker-compose.yaml
#
# To create a development environment with docker-compose
# https://cylab.be/blog/336/use-docker-compose-to-create-a-dev-environment-for-laravel
#
services:
  node:
    image: node:18.18.0-alpine
    # replace by your actual UID and GID
    # or define these in a .env file
    user: "${UID}:${GID}"
    working_dir: /app
    volumes:
      - .:/app
    entrypoint: /bin/sh -c "npm install && npm run watch-poll"

Installation

ESLint can/should be installed using npm:

npm install --save-dev eslint @eslint/js

Or, if you are using docker compose:

docker compose exec node npm install --save-dev eslint @eslint/js

Globals

As we will see below, in the configuration of ESLint we will use globals definitions, which require the globals npm package which you can install with:

npm install --save-dev globals

or:

docker compose exec node npm install --save-dev globals

Configuration

In your project’s root directory, create a file named eslint.config.mjs with the following content.

The .mjs extension tells npm that this is a javascript module. Otherwize you may encounter errors like Warning: To load an ES module, set "type": "module" in the package.json.

//
// eslint.config.mjs
// https://cylab.be/
//
// run with
// docker compose exec node npx eslint resources/js/**
// or
// npx eslint resources/js/**
//

import js from "@eslint/js";
import globals from "globals";

export default [
    js.configs.recommended,

    {
       languageOptions: {
            globals: {
                ...globals.browser
            }
        }
    }
];

In this configuration, we start with the recommended configuration for ESLint, which you can find at https://github.com/eslint/eslint/blob/main/packages/js/src/configs/eslint-recommended.js

If your are writing code to be executed in a web browser, you expect some global objects to be available like window, console and document. To make ESLint aware of this fact, we also add the global.browser language option. Otherwize you will encounter errors like error 'window' is not defined no-undef.

Usage

We are now set and can run ESLint with

npx eslint resources/js/*.js

Or:

docker compose exec node npx eslint resources/js/*.js

eslint.png

Additional rules

Once started, you can add additional rules to your configuration, like no-implicit-globals

https://eslint.org/docs/latest/rules/no-implicit-globals

To goal of this rule is to avoid ‘polluting’ the global scope with variables that are intended to be local to the script.

You can add it to your eslint.config.mjs like this:

import js from "@eslint/js";
import globals from "globals";

export default [
    js.configs.recommended,

    {
        rules: {
            // https://eslint.org/docs/latest/rules/no-implicit-globals
            "no-implicit-globals": "error",
        }
    },

    {
       languageOptions: {
            globals: {
                ...globals.browser
            }
        }
    }
];

Working with multiple scripts

If your code is spread over multiple scripts, like in the simple example below, you may define in the first scripts (jquery.js or script1.js) some global objects, that you want to use in the latter (script2.js).

<script src="/jquery.js"></script>
<script src="/script1.js"></script>
<script src="/script2.js"></script>

To make ESLint aware of this, you can add the following lines at the top of script2.js:

// jquery will be loaded by jquery.js
// disable eslint error '$' is not defined:
/* global $ */

This blog post is licensed under CC BY-SA 4.0

This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept