Painless Migration of tslint to eslint — Angular

Post Image

Why?

As you probably know, TSLint has been deprecated since 2019. But, until now, the Angular CLI was still generating projects with built-in support for TSLint, so most Angular developers out there have TSLint in their projects. With the upcoming Angular CLI v12 release, this is no longer the case: the CLI now generates projects without the lint configuration. Angular v12 will also require TypeScript v4.2, and TSLint is misbehaving with this new version (and that's probably not going to be fixed of course).

All this points to an obvious task for us Angular developers: we have to migrate to eslint.

ESLint and Angular

TSLint integrated well with Angular since it was designed from the ground up to work with typescript. Using ESLint with an Angular project is actually a complex use-case requiring extending ESLint with quite a few separate packages.

Our savior is @angular-eslint; an open-source project which makes converting your Angular project to ESLint easy. They've done the hard work of extending ESLint with all the necessary dependencies, configuring Angular to work with it, and packaged it up in a schematic.

Finally the steps of Migration

Step 1: Pre-requisite

Please update your tslint, as schematics will not migrate if you have an older version than 5.x. Use the command below to get the latest

npm i tslint@latest

Step 2: Running @angular-eslint

A. Add @angular-eslint to your project:
ng add @angular-eslint/schematics

If you have an Angular 12 project (without tslint), you're done!

B. For migration from tslint on Angular 11 or 12, run the following:
ng g @angular-eslint/schematics:convert-tslint-to-eslint --remove-tslint-if-no-more-tslint-targets

If you are on Angular 9 or 10, an older version of the schematic gets installed and the convert command differs slightly. You may want to prioritize upgrading Angular before converting to ESLint. But if you really want to upgrade linting first, use this command:

ng g @angular-eslint/schematics:convert-tslint-to-eslint <project-name-here>

The above command will do the following for you:

  • Read your chosen project's tslint.json and use it to CREATE a .eslintrc.json at the root of the specific project which extends from the root config (if you do not already have a root config, it will also add one automatically for you). - The contents of this .eslintrc.json will be the closest possible equivalent to your tslint.json that the tooling can figure out. - You will want to pay close attention to the terminal output of the schematic as it runs because it will let you know if it couldn't find an appropriate converter for a TSLint rule, or if it has installed any additional ESLint plugins to help you match up your new setup with your old one.
  • UPDATE the project's architect configuration in the angular.json to such that the lint "target" will invoke ESLint instead of TSLint.
  • UPDATE any instances of tslint:disable comments that are located within your TypeScript source files to their ESLint equivalent.
  • If you choose YES (the default) for the --remove-tslint-if-no-more-tslint-targets option, it will also automatically remove TSLint and Codelyzer from your workspace if you have no more usage of them left.

Step 3: Fix Linting issues

Now your project is successfully migrated to eslint and you should be good to run ng lint command, It will probably find some issues, like trailing spaces, and naming convention rules. Most of these can be automatically fixed with the following command. ng lint –fix You should now see some changed files. ESLint fixes everything it can but it won't change everything for you. you shouldn't have too many new things to fix. If you have some false positives, don't worry, these won't prevent your build from succeeding.

Step 4: Clean up (For Angular v10 or earlier)

As we are using eslint, we do not need tslint anymore

  • Delete tslint.json file from the root and src/
  • Remove tslint package npm uninstall tslint --save

You're done now. If you still find some errors you may update the rules in .eslintrc.json based on the errors or can solve it!

Bonus

Most of the time we didn't check our code linting before committing and end up maintaining the bad code and solving the errors at last

So, I have a solution for this: check linting before each commit in the staged files and avoid bad commits by you or every contributor in the same repo.

we will need a couple of packages that will automate this process

npm i husky lint-staged --save-dev

Add new settings for this plugin in package.json:

"scripts": {
            ...,
          },
          "husky": {
            "hooks": {
              "pre-commit": "lint-staged --relative"
            }
          },
          "lint-staged": {
            "src/**/*.{ts,html}": [
               "eslint --fix"
            ]
          },

One thing I love about this is it only runs linting on staged files and ignore the rest

That's about it, now this will run linting before each commit and will save the efforts to check code pattern errors in PR's

Conclusion

That about wraps it up. Your app is now future-proof! At least on the linting front. Keep an eye out for new versions of @angular-eslint to fix open issues.

Happy Coding!

BM
Written by Bhavin Matariya

Software engineer, I love to help other developers by answering questions on stackoverflow, writing helpful tech blogs.