ESLint x Prettier: The Right Way To Start A JavaScript Project

ESLint x Prettier: The Right Way To Start A JavaScript Project

June 29th, 2024 | 5 mins read

Published on dev.to and medium.com

In 2022, ESLint (v8.21.0) introduced a new configuration system nicknamed "Flat Config." This post is dedicated to this edition.

It's very easy to initialize a new JavaScript project; you just need a code editor, a runtime environment, a terminal, and you're good to go!

Similarly, it's just as easy to ruin a web project by making the code unreadable, unmaintainable, and thus generating technical debt...

Indeed, since JavaScript is a very loosely typed language, anything is quickly allowed:

  • Omitting semicolons at the end of lines;
  • Using single and double quotes within the same block of code;
  • Declaring variables but not using them;
  • Lines of code that are too long...

This flexibility of the language is both a strength and a weakness, which should be addressed by defining best practices before development begins. Thus, properly structured code will promote collaborative work and the scalability of the project.

To achieve this, there are two essential tools that will bring rigor to your web project: the linter and the formatter.

Definitions:

Linter: A code analysis tool that detects syntax issues.

Formatter: A tool that formats the code to make it readable.

NB: I insist on the fact that these are two distinct tools. Although the linter can format some parts of the code, it isn't its role. This task is reserved for the formatter.

Starting Your JavaScript Project

To illustrate how each tool works, I suggest creating a new JavaScript project (without a framework) using ViteJS.

npm create vite@latest my-awesome-project -- --template vanilla

Like a recipe, let's install the initial dependencies provided with ViteJS, and then add the new libraries: ESLint and Prettier!

npm install --save-dev eslint @eslint/js prettier eslint-config-prettier eslint-plugin-prettier

NB: For future reference, a project scaffolded with ViteJS operates directly in module mode. This means your .js files are implicitly .mjs files. Likewise, you will need to explicitly name your files .cjs to write with CommonJS syntax.

Once the linter and formatter dependencies are correctly installed, you still need to create their respective configuration files: eslint.config.js and prettier.config.js.

NB: ESLint and Prettier configuration files can take several forms, including the following: .eslintrc.js, .eslintrc.cjs, .eslintrc.json, .eslintrc.yaml, .prettierrc, .prettierrc.json, .prettierrc.yaml, .prettierrc.js, prettier.config.cjs, or .prettierrc.toml.

Linter Configuration

Let's start by setting up the linter to use it in our new project.

Here is an initial version of the eslint.config.js file:

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

export default [
  {
    files: ['**/*.js', '**/*.jsx']
  },
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node
      }
    }
  },
  js.configs.recommended,
  {
    rules: {
      'no-console': 'warn'
    }
  }
];

This initial configuration is sufficient to run ESLint from a new terminal to check the syntax of JavaScript files: npx eslint [file|dir]

I recommend adding this execution as a script in your package.json: npm run lint

{
  "name": "my-awesome-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint"
  },
  "devDependencies": {
    "@eslint/js": "^9.5.0",
    "eslint": "^9.5.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.0",
    "prettier": "^3.3.0",
    "vite": "^5.2.0"
  }
}

By adding a console.log() statement in a .js file of your project, you should get the following result after invoking the linter.

/home/dmnchzl/my-awesome-project/counter.js
  5:5  warning  Unexpected console statement  no-console

βœ– 1 problem (0 errors, 1 warning)

Prettier Configuration

Now, let's set up the formatter by editing the prettier.config.js file:

export default {
  arrowParens: 'avoid',
  printWidth: 120,
  semi: true,
  singleQuote: true,
  trailingComma: 'none'
};

NB: Prettier has a default configuration. In the above file, I only override the parameters I want for my project.

Similar to ESLint, you now just need to run Prettier (npx prettier --write [file|dir]) to format the JavaScript files.

It's also possible to save a new script in your package.json: npm run format

{
  "name": "my-awesome-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint",
    "format": "prettier --write \"**/*.{js,jsx}\""
  },
  "devDependencies": {
    "@eslint/js": "^9.5.0",
    "eslint": "^9.5.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.0",
    "prettier": "^3.3.0",
    "vite": "^5.2.0"
  }
}

ESLint x Prettier

The last step is to interface the two tools! This means controlling the formatter's syntax through the linter.

To do this, simply add Prettier's configuration to the ESLint rules (don't forget to enable the plugin):

import globals from 'globals';
import js from '@eslint/js';
import prettierRecommended from 'eslint-plugin-prettier/recommended';

export default [
  {
    files: ['**/*.js', '**/*.jsx']
  },
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node
      }
    }
  },
  js.configs.recommended,
  prettierRecommended,
  {
    rules: {
      'no-console': 'warn',
      'prettier/prettier': [
        'warn',
        {
          arrowParens: 'avoid',
          printWidth: 120,
          semi: true,
          singleQuote: true,
          trailingComma: 'none'
        }
      ]
    }
  }
];

And there you go! From now on, ESLint will be able to alert you whenever the Prettier format is not respected.

Try removing one or more semicolons at the end of a line or misaligning your lines...

/home/dmnchzl/my-awesome-project/counter.js
  2:18  warning  Insert `;`                      prettier/prettier
  3:22  warning  Replace `(count)` with `count`  prettier/prettier
  4:20  warning  Insert `;`                      prettier/prettier
  5:46  warning  Insert `;`                      prettier/prettier
  6:4   warning  Insert `;`                      prettier/prettier
  7:67  warning  Insert `;`                      prettier/prettier
  8:16  warning  Insert `;`                      prettier/prettier

Now you know that the rigor of a web project does not come alone; it also relies on many tools, including the linter and the formatter.

To go further, I invite you to install the ESLint and Prettier extensions, depending on your favorite code editor (Visual Studio Code in my case). This way, you will benefit from additional features such as syntax highlighting when linting rules are not followed, or automatic code formatting upon file saving.

Enjoy πŸ‘