Use ESLint and Prettier correctly and never see ugly code again

Stop using eslint-disable and use efficient static analysis in your project

Maintaining clean and consistent code is essential in web development. However, it gets challenging when you are collaborating on a project with multiple developers. That’s where the static analysis steps in with some tools like ESLint, Prettier, and Husky — they help developers ensure code quality and adherence to best practices. In this blog post, we will explore the static analysis, how to configure ESLint, Prettier, and Husky properly and say farewell to eslint-disable statements.

Understanding Static Analysis

Static analysis refers to the process of examining code without executing it. This analysis aims to identify potential errors, enforce coding standards, and detect stylistic inconsistencies. A project using efficient static analysis helps developers to catch issues early in the development cycle, leading to fewer bugs, improved code readability and maintainability.

Linters X Formatters

LinterFormatter
PurposeAnalyze source code to detect and report on patterns that might be errors or could lead to errors.Focus on code formatting and layout rather than identifying potential errors.
FunctionalityExamine code against predefined rules, checking for potential bugs, syntax errors, stylistic inconsistencies, or code smells.Automatically adjust code indentation, line breaks, spacing, and other formatting aspects to ensure consistency and readability.
ExamplesESLint for Javascript, RuboCop for RubyPrettier for most of the languages, gofmt for Go

Prettier: The Code Formatter

Prettier is the code formatter for various languages. It is opinionated, which means that it enforces a specific formatting convention for every language. Integrating Prettier into your workflow helps eliminate debates over code style and saves time by automating the formatting process.

To integrate Prettier into your project, you can install it via npm:

npm install --save-dev --save-exact prettier
echo {}> .prettierrc.json

Once installed, you can run Prettier from the command line or integrate it with your code editor for real-time formatting.
If your team, for any reason, wants to use unconventional formatting rules in your project, don’t worry! Prettier rules are configurable and you can check on its documentation how to adapt the .prettierrc.json for your preferences.

ESLint: The Linter

ESLint is a linter for ECMAScript standardized languages. If your project uses a framework like React or NextJS, probably the ESLint is already set up with some initial rules. It is possible to combine ESLint and Prettier with the eslint-plugin-prettier plugin, which allows ESLint to show formatting errors and ESLint issues. Also, you can use eslint-config-prettier to disable ESLint rules that conflict with Prettier.

Here’s how you can set it up:

  1. Install ESLint and the plugins:
    npm install --save-dev eslint eslint-plugin-prettier eslint-config-prettier
  2. Configure ESLint to use Prettier rules by extending eslint-config-prettier:
    {
    "extends":  ["eslint:recommended", "plugin:prettier/recommended"]
    }

ESLint provides many configurable rules. Let’s see some examples :

no-unused-vars

This is one of the most common and important rules of ESLint. This rule is aimed at eliminating unused variables, functions, and function parameters.

no-nested-ternary

This rule disallows nested ternary expressions. Using ternary can improve our code readability; however, nested ternary runs in the opposite way.

no-magic-numbers

‘Magic numbers’ are numbers that occur multiple times in code without an explicit meaning. They should preferably be replaced by named constants.

The ESLint docs provides more details and how to configure these rules in your .eslintconfig file.

The Problem with eslint-disable

ESLint has a highly configurable nature, this causes a side effect of multiple eslint-disable statements in the codebase. These statements serve as a temporary workaround to silence linting errors or warnings. However, as the saying goes, "There’s nothing more permanent than a temporary solution."

Let’s understand the disadvantages of eslint-disable:

  1. Code Quality Compromise:
    eslint-disable statements suppress linting errors without addressing the underlying issues. This will introduce inconsistencies into the codebase, making it harder to maintain a unified coding style.

  1. Risk of Ignored Issues:
    By silencing eslint warnings or errors, developers may overlook legitimate code issues that could lead to bugs or other issues.

  1. Technical Debt Accumulation:
    Over time, eslint-disable statements can accumulate technical debt, as unresolved linting issues persist and compound.

When it is OK to use eslint-disable ?

  1. Temporary Workarounds:
    In some emergencies, you can silence the errors or warnings until a permanent solution is implemented (make sure that will be implemented).
  2. Third-Party Code:
    When working with third-party libraries or dependencies that trigger eslint warnings or errors outside of your control. This is a very common situation because every project has its specific lint configuration and they may conflict.
  3. Legacy Code:
    Last but not less scary important, it can be used strategically to suppress warnings in legacy code while gradually refactoring and improving adherence to linting rules over time.

Husky: The pre-commit tool

Husky is a popular tool used for managing Git hooks. Git hooks are scripts that Git executes before or after certain actions such as commits, merges, or pushes. It’s worth noting that Husky offers much more than just pre-commit hooks. It deserves a dedicated blog post solely focused on exploring how you can improve your development process with it.

Combining Husky, ESLint, and Prettier, we can perform static analysis automatically before the commit is made, ensuring that the changes committed will follow the linter rules. With this approach, our project will have a cleaner commit history, as Husky will prevent non-standardized code from being committed.

Let’s see how to set it up:

  1. Install Husky, lint-staged, and commitlint:
    npm install husky lint-staged @commitlint/{config-conventional,cli} --save-dev
  2. Configure your package.json,your package.json will look like this:
    {
    "name": "your-project",
    "version": "1.0.0",
    "description": "Your project description",
    "main": "index.js",
    "author": "Your Name",
    "license": "MIT",
    "scripts": {
    "check-commit": "echo \"Checking commit message...\" && commitlint -E HUSKY_GIT_PARAMS",
    "lint": "eslint .",
    "lint:fix": "eslint --fix ."
    },
    "devDependencies": {
    "@commitlint/cli": "^13.1.0",
    "@commitlint/config-conventional": "^13.1.0",
    "eslint": "^8.6.0",
    "husky": "^7.0.4",
    "lint-staged": "^12.1.6"
    },
    "lint-staged": {
    "*.js": [
      "eslint --fix",
      "git add"
    ]
    },
    "husky": {
    "hooks": {
      "pre-commit": "lint-staged && npm run check-commit"
    }
    },
    "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
    }
    }
  3. Configure commitlint:
    Create a commitlint.config.js file in your project and add the following content

    module.exports = {
    extends: ['@commitlint/config-conventional']
    };

    We’re all set! Our project is now equipped with a solid static analysis setup. It’s time to take a deep dive into it. Enjoy, and keep coding!

Conclusion

In this post, we’ve covered a wealth of knowledge. Let’s recap what we’ve learned:

  • We understood what is Static Analysis and its importance in software development.
  • We learned how to integrate essential tools like Prettier, ESLint, and Husky into our workflow, enabling automated code formatting and quality assurance.
  • We learned the disadvantages of using eslint-disable, when it’s ok to use it and learned alternative approaches for maintaining code quality effectively.

We want to work with you. Check out our "What We Do" section!