Apply ESLint rules gradually to your legacy project

by mmyoji

2 min read

It's not hard at all to introduce ESLint to a new project, but so hard for a legacy project.

Although there are several ways to do this, I'll leave a better way for myself.

Steps

  1. Upgrade eslint version as far as possible
  2. List up "rules" w/ "error"
  3. Add TODO list in "overrides" per directory w/ "warn"
  4. Run with --max-warnings=0 option to newly added files on CI

1. Upgrade eslint version as far as possible

If eslint libs are installed in your project, you should upgrade them as far as possible.

The rules may behave differently and have better options after the upgrade.

2. List up "rules" w/ "error"

After upgrading or installing the eslint libs, you would set up .eslintrc.js.

By the way, I'm explaining this with the old eslint config file in this post. But the technique itself is also applicable to new config file.

// .eslintrc.js

module.exports = {
  // ...

  rules: {
    "@typescript-eslint/no-implicit-any": ["error"],
  },
  // ...
};

In this phase, your project may not have passed eslint on CI, but it's OK for now.

3. Add TODO list in "overrides" per directory w/ "warn"

To mitigate the violations, you can list up the directory list with "warn".

Suppose your project is built using the MVC style.

// .eslintrc.js

module.exports = {
  // ...

  overrides: [
    // TODO: remove listed dir after fixing the violations.
    {
      files: [
        "src/controllers/admin/**/*.ts",
        "src/controllers/web/**/*.ts",
        "src/models/**/*.ts",
        "src/lib/**/*.ts",
      ],
      rules: {
        "@typescript-eslint/no-implicit-any": ["warn"],
      },
    },
  ],
};

For example,

  1. fix no-implicit-any violations under the src/controlles/admin/*
  2. remove the line "src/controllers/admin/**/*.ts"
  3. violations can be detected under the directory

4. Run with --max-warnings=0 option to newly added files on CI

This is an optional, but very effective.

You can apply stricter rules to new files. This can be done with the following command:

# `remotes/origin/main` can be replaced with your base branch.
$ eslint \
    --max-warnings=0 \
    $(git diff --name-only --diff-filter=A remotes/origin/main HEAD)

ref: https://stackoverflow.com/a/15535048

If the new files are violated against any "warn" rules, they are detected as "error".

You can avoid violated files are added in your project.