SharePoint Framework with ESLint

If you're still using tslint, I have bad news for you - it has been deprecated a long time ago. If tslint works for your old projects, then it's ok. However, for new projects use eslint. ESLint nowadays supports TypeScript with help of a plugin and parser. 

SharePoint Framework build pipeline is not as fast as the JavaScript tooling world and still uses tslint as a default linter. The good news is that we can fix it!

The source code for this post you can find on GitHub here.

Prerequisite

Scaffold a new react based SharePoint Framework solution or open any of your existing ones. 

Install the required packages

First of all, we need eslint and some essential related plugins. Let's install them:

npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin gulp-eslint7 eslint-plugin-react --save-dev
  • eslint - is a linter itself
  • gulp-eslint7 - corresponding eslint gulp plugin (supports latest eslint)
  • eslint-plugin-react - contains recommended rules for React-based projects
  • @typescript-eslint/parser - a custom eslint parser, so that eslint understands what is TypeScript
  • @typescript-eslint/eslint-plugin - contains recommended rules for TypeScript

Create a file with rules

You can use the .eslintrc.json file to list all your rules (eslint follows cosmiconfig, so you can use different config options). 

This is the bare minimum configuration needed:

{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "ignorePatterns": ["*.js"],
  "plugins": [
    "@typescript-eslint"
  ],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended"
  ]
}

The essential things here are:

  • plugins section contains definition for @typescript-eslint
  • parser set to @typescript-eslint/parser
  • extends defines a set of recommended rules for TypeScript and React

Disable tslint task

Since we don't need tslint anymore, simply delete tslint.json. Open gulpfile.js and before initialization put a line

build.tslintCmd.enabled = false;

That way we completely disabled the default tslint task.

Inject ESLint task into the SharePoint Framework pipeline 

To make it work, we should create a custom build pipeline task and add it to the SPFx pipeline.

Again edit gulpfile.js and insert the below code:

const eslint = require('gulp-eslint7');

const eslintSubTask = build.subTask('eslint', function (gulp, buildOptions, done) {
  return gulp.src(['src/**/*.{ts,tsx}'])
    // eslint() attaches the lint output to the "eslint" property
    // of the file object so it can be used by other modules.
    .pipe(eslint())
    // eslint.format() outputs the lint results to the console.
    // Alternatively use eslint.formatEach() (see Docs).
    .pipe(eslint.format())
    // To have the process exit with an error code (1) on
    // lint error, return the stream and pipe to failAfterError last.
    .pipe(eslint.failAfterError());
});

build.rig.addPreBuildTask(build.task('eslint-task', eslintSubTask));

In the task, we simply grab all our sources and send them to eslint. You can control, whether you want to fail the build if there are errors. 

I added registration to pre-build, but you can add it to the post-typescript or even to post-build. Just anything which suites you best. 

Run it and fix errors

If you run gulp serve on the default React-based solution, you will see an error:

Recommended settings for TypeScript don't like "{}" definitions. You can either disable this rule or just use an unknown type on the default web part:

class HelloWorld extends React.Component<IHelloWorldProps, unknown>

That's it! Hope it helps you integrate eslint faster in your SharePoint Framework project. 

The source code for this post you can find on GitHub here.

Title image credits: FreeVector.com