Skip to content

Instantly share code, notes, and snippets.

@Jarmahent
Created March 17, 2019 19:39
Show Gist options
  • Save Jarmahent/85524757a063b719d1bea06d127aeaf6 to your computer and use it in GitHub Desktop.
Save Jarmahent/85524757a063b719d1bea06d127aeaf6 to your computer and use it in GitHub Desktop.

Getting started with custom ESlint rules

Everyone can agree that Eslint is an extremely useful tool for programmers to keep their code looking nice and tidy for others, but sometimes Eslint doesnt provide a specific rule to some developers who are looking for a specific solution. Thankfully Eslint gives you the power to create your own custom rules just incase you the already provided rules are not enough.


Setting up your enviornment

Download Yeoman to help you generate the eslint plugin boilerplate:

npm install -g yo

after that we install yo succesfully we want to install the eslint generator that works with yeoman

npm install -g generator-eslint


Creating plugin boilerplate

Now that we have yo and the eslint-plugin generator installed. We can use them together and generate our boiler plate. Lets make a directory where our plugin will be held

$ mkdir example_eslint_plugin

inside of this new directory we made lets run yo with

$ yo

A prompt will pop up, lets go ahead and run the eslint-plugin generator:

yopic

We will be prompted to pick if you want to make a rule or a plugin. Since we do not have anywhere to put a rule yet, we want to create the plugin boilerplate first.

You will be prompted for a few things after you tell it to create a plugin:

eslintfinish


Generating a custom rule

Now that we have the plugin created we can go ahead and run yo again but instead of telling the eslint-generator to create a plugin we tell it to create a rule.

You will be prompted for a few things:

link2


Working Tree explained

You have just generated your first eslint plugin congratulations! As of now it does nothing but we can change that! Now that we have our work enviornment set up and ready to go lets explore what was created.

Over in docs we have the documentation for all of your rules. You can edit the .md files to explain the rules you've created in more detail.

inside of the lib directory is where our index.js file sits and is where the rule runs. inside of lib/rules is where all of your custom rules will be held and this is where most of your work will be done when creating custom rules.

and last but not the least is the test directory. As the name says this is where all of our test will run to make sure our rules work correctly!


Writing out the rule

Now that we understand what the files are, lets go over to lib/rules/<your_rule_name.js>

This file has 2 main sections that we want to look at and focus. The meta section and create: function(context) section.

The meta section is where Eslint will look for information about your plugin

meta: {
       docs: {
           description: "Eslint Rule Example!",
           category: "<category>",
           recommended: false
       },
       fixable: null,  // or "code" or "whitespace"
       schema: [
           // This is where your rule options will be
       ]
   }

The function(context) section is where the heart of your rule lies. This is where you will be writing the logic for your rule.

create: function(context){
  return{
    // This is where your rule will be held
  };
}

Lets write a simple rule that only allows a maximum of 3 comments per file and then we'll break it down and explain everything in context.

create: function(context){
  Program: function(node){
    const comments = node.comments;
    const maxComments = 3;

    if(comments.length > maxComments){
      context.report({
        node: node,
        message: "More than 3 comments in your file have been detected"
      })
    }
  }
}

Now lets break this code down and explain what every line does...

  1. create: function(context)

"The context object contains additional functionality that is helpful for rules to do their jobs. As the name implies, the context object contains information that is relevant to the context of the rule"

Working with rules Eslint

  1. Program: function(node){}

In this line we tell Eslint that we want to be working with the Program Node in the AST(Abstract Syntax Tree), which is usually the very first node. The function called for this has node object that will be vital to us for making a rule

  1. const comments = node.comments;

As stated before the node object contains other objects and one of those objects is all the comments in a program which is usually an array.

  1. const maxComments = 3;

This line is self explanatory we're just assigning the number 3 to the variable name maxComments

  1. if(comments.length > maxComments){}

This line is also self explanatory, we're just gonna fire this if statement if the amount of comments in the program is larger than 3.

  1. context.report({})

Here we're calling the context.report function, you will be using the function a lot!

For now we will pass the violating node to the context.report function and the message that will be shown to the user when a rule violation is made.

context.report({
  node: node,
  message: "Your Message here"
});

Running tests on your rule!

Now that we've created our rule we want to make sure that the rule actually works.

Lets head over to test/lib/rules/<your_rule_name>.js

The main focus of this tester is:

var ruleTester = new RuleTester();
ruleTester.run("max-3-comments", rule, {

    valid: [
    `
    // This is valid
    // No more
    // than 3 comments.
    `
    ],

    invalid: [
        {
            code: [
            `
            //
            // This should throw an error because
            // there are more than 4 comment lines.
            //
            `
            ],
            errors: [{
                message: "Fill me in.",
                type: "Me too"
            }]
        }
    ]
});

Now we run our rest and make sure they are valid.

Another way of making sure our rule works is heading over to astexplorer.net

This website allows you to view the AST of a .js file and test it for errors using your own custom eslint rule.


Running your rule on an existing code base.

Now that we've created our plugin and our own custom rule we want to put it to use right?

Lets go ahead and install this plugin onto an existing code base and add it to the .eslintrc.json file.

While you're inside the existing code base go ahead and run:

$ npm install ../location/of/your/plugin

$ yarn add ../location/of/your/plugin

this will install the the plugin and it will add it to your package.json file.

Now we can head over to the .eslintrc.json file and add in our custom plugin.

{
    "env": {
        "es6": true,
        "node": true
    },
    "extends": "eslint:recommended",
    "plugins": [
      "example_eslint_plugin"
    ],
    "parserOptions": {
        "ecmaVersion": 2016,
        "sourceType": "module"
    },
    "rules": {
      "example_eslint_plugin/max-3-comments": ["error"]
    }
}

Now that we've added the rule to our .eslintrc.json file we run eslint like any other rule with:

eslint . --ignore-pattern test

If you there an file with more than 3 comment lines then the rule will fire and you will get an error message similar to:

// No more than 3 comments per file (at 4:14)
   // 4 Comments
// -------------^

Congratulations you have just created your first custom eslint plugin and rule.

Resources:

Working with Eslint Rules A more thorough explanation of how eslint rules work.

AST Explorer An extremely useful tool to show you the AST of a js file and show you your rule errors in realtime.

Writing Eslint rules for picky Developers by William Humphreys-Cloutier Another tutorial for custom Eslint rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment