In my last post about Fixing the “can’t find custom rule directory: tslint-microsoft-contrib” error in SPFx projects, I explained a random error that can pop up with your SharePoint Framework (SPFx) projects as well as how to fix it. But in that post, I mentioned something in passing:
At the time, TSLint was the de facto standard linter for TypeScript projects. With the TypeScript 2019 roadmap post, the TSLint team decided to deprecate their own tool and work to focus their efforts on contributing to ESLint:
“In order to avoid bifurcating the linting tool space for TypeScript, we therefore plan to deprecate TSLint and focus our efforts instead on improving ESLint’s TypeScript support."
Good question, but unfortunately I can’t answer that question. It’s been asked before as you can see from issues in the sharepoint/sp-dev-docs issue list & from a UserVoice entry: SPFx: ESLint instead of TSLint.
If history has shown us anything with SPFx, they’re slow to adopt the latest, or even recent, tech. Remember how long it took to adopt support for Node.js v12 & v14? It only took 17 months to support Node.js v12 after it gained status as the active LTS version. But I digress…
Regardless… why do you have to wait for Microsoft to switch? You don’t!
You can swap TSLint out today and use ESLint, and in this post I’ll show you how!
Today, the current version of SPFx is v1.12.1 which defaults to use TypeScript v3.7. Due to the large dependency tree Microsoft adopted for the SPFx build toolchain, you can’t easily use the latest version of ESLint (v7), instead you’ll be stuck with ESLint v6 for the time being.
This isn’t a bad thing, I just mention it because if you’re reading the docs for ESLint, you should be aware of it as they default to the latest version.
You can get around this if you upgrade your project to TypeScript v3.9 though. To see how to do this, see my post: Use Different Versions of TypeScript in SPFx projects.
The first step is to remove that deprecated TSLint tool from your project, as well as all related files.
Within the file ./gulpfile.js, locate the following line:
Add the following line immediately before the line that calls
// disable tslint build.tslintCmd.enabled = false;
Finally, delete the ./tslint.json file from your project as you don’t need it anymore.
With TSLint removed, the next step is to install a few dependencies.
These add ESLint and a few plugins to support linting TypeScript projects with ESLint. These include the following:
- eslint: the tool used to identify & report patterns found in your TypeScript code
- @typescript-eslint/parser: An ESLint parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code.
- @typescript-eslint/eslint-plugin: An ESLint plugin which provides lint rules for TypeScript codebases.
- gulp-eslint: A gulp plugin for processing files with ESLint
You can install these using the following command:
npm install [email protected] @typescript-eslint/[email protected] @typescript-eslint/[email protected] [email protected] --save-dev --save-exact
The next thing you’ll need to do is create a configuration for ESLint. This serves the same role as the tslint.json file. Since SPFx projects already have a ./config folder, that seems like a natural place for all configuration stuff.
Create a new file ./config/eslint.json and add the following to it:
Refer to ESLint: Configuring ESLint docs for details on this file, but remember you’re using an outdated version of ESLint.
ignorePatterns property (see ESLint:
ignorePatterns in Config Files). This means we have to use the older
.eslintignore option supported by ESLint v6.
Add the file ./.eslintignore to the root of your project and add the following to it:
The last step is to update your project’s Gulp configuration to support a new eslint task as well as do what the default project did with TSLint: run ESLint as a subtask when you execute gulp build.
Within the ./gulpfile.js file, locate the lines you added to disable TSLint. Next, add the following immediately after that, but before the call to build.initialize():
This first loads the ESLint gulp task and then creates a subtask. The subtask pipes all TypeScript & TypeScript Extended files through ESLint, using the configuration file we created. If it finds any issues with the code, the build will fail, matching the same experience we had in the default TSLint configuration in SPFx projects.
Finally, it adds the new ESLint task both as its own task that you can run on its own, but also as a subtask to the gulp build task. You can see the task by executing gulp –tasks:
Let’s see how it works! Execute the task, either by entering gulp eslint or gulp build:
While everything is working, it seems the default code is ok. Let’s add a rule to our config to force some issues to appear. Within the ./config/eslint.json file, add the rule
array-bracket-newline to the configuration file so it looks like the following:
This tells ESLint that all arrays should be defined on a single line, just like you see it listed for the rule. This will certainly throw some errors due to the code in our default webpart’s
Now rerun ESLint to see the results:
Fantastic, you’re now using ESLint!
If you’ve updated your SPFx project to use TypeScript v3.9, you can make a few changes to the steps above to implement a few optimizations.
If you haven’t already, upgrade your project to TypeScript v3.9. To see how to do this, see my post: Use Different Versions of TypeScript in SPFx projects.
If you already installed the dependencies using the script above, repeat that step to get the most current stuff available. You’ll see the two @typescript-eslint/* packages will jump from v2 to v4 and the eslint package will jump to v7.
ESLint v7 supports specifying the file patterns you want to ignore using a property in the config file, rather than a dedicated ignore file.
Add the following to your ./config/eslint.json file:
Now you can delete the ./eslintignore file in the root of your project.
Congrats, you’re now leveraging the latest version of ESLint!