Custom eslint rules

Valeriy Kuzmin,

Lilt, 2020

The little problem

The actual problem

// @typescript-eslint/explicit-module-boundary-types

// no error !!!
module.exports.myFunc = (arg1: number, arg2, 
                         arg3: boolean) => {
  ...
} 
  
// an error
export const myFunc = (arg1: number, arg2, 
                       arg3: boolean) => {
  ...
} 

The grand problem

JS

TS

The grand problem

The restrictions

  • Humans are not really scalable
  • The knowledge is not uniform
  • It's damn hard to do manually
  • Product needs to be developed
  • We have a ton of bad code

The answer

Automation! Tons of it.

The grand strategy

Rule 1: use TS & Eslint

Rule 2: boundaries

Rule 3: no problematic code

Time

Abstract Syntax Tree

a + b

Binarry expression

Operator +

Left:

variable a

Right:

variable b

Abstract Syntax Tree

module.exports = 456;

Visitors

AssignmentExpression(node) {
        try {
          if (
            _.get(node, "left.object.name") === "module" ||
            _.get(node, "left.object.property.name") === "exports" ||
            _.get(node, "left.object.name") === "exports" ||
            _.get(node, "left.name") === "exports"
          ) {
            context.report({ messageId: "noModuleInTsError", node });
          }
        } catch (error) {
          context.report({
            node,
            messageId: "unknownError"
          });
        }
      }
    };

Apparently our version of parser is a bit buggy, hence _.get

A good rule

  • Description
  • Sensible error text
  • Suggestion what to do
  • Tests
  • Added to our config
  • File exceptions if needed
  • Auto-fix

.eslintrc.js:

"local-rules/no-module-in-ts": 2

eslint-local-rules.js:

"no-module-in-ts": require("./libs/eslint/rules/no-module-in-ts").default

Profit

  • I don't need to look for this in PRs
  • Criticism from robots is better
  • We have a template and can make more rules
  • TS is enforced better
  • We can go further!

What's next?

  • Automatic fixes for code via eslint. Easier progression of the grand plan.
  • JSCodeShift transforms for auto-refactoring. E.g.  then await
  • Much more specialized rules, unique for our codbase

Call to action

My personal CTA: no rule exceptions in .eslintrc, only inside files (item 2 in the form)

Thanks!

Questions?

Made with Slides.com