Search code examples
angulareslinttypescript-eslintangular-eslint

Extending multiple rule-sets using "typescript-eslint/recommended" with "@angular-eslint/recommended" is this okay to do?


     I have downloaded and installed ESLint rule-sets as packages to my current project. The rule sets I downloaded are for adding ESLint support for Angular, TypeScript, (and of-course ECMAScript) to the project environment. I want to create a ESLint configuration, that contains the "standardized code-style" that I need the developers, who are working on the project to adhere to.

     At first I added plugin:@typescript-eslint/recommended. Later I decided to make a change, and I switched to using plugin:@angular-eslint/recommended. I thought that Angular-eslint-recommended extended the rule-set from the TS-ESLint plugin: plugin:@typescript-eslint/recommended, but in fact, it only extends plugin:@typescript-eslint.

Question: Is it okay to extend multiple rule-sets? And would extending plugin:@typescript-eslint/recommended & plugin:@angular-eslint/recommended be all the rules I need to have proper Linting support for my TS-Angular Project?





Solution


  • There is no Limit to the Qty of Rule-sets You Can Extend


    But know that the order you use to extend them makes a Difference

            This is because rule-sets override other rule-sets placed after them, in other words; the first rule-set you place in the .eslintrc.json file's "extends": [] array-field, is going to take precedence over all of the other rule-sets that have also been extended using the "extends" field.


    This is What the Previous Statement Boils Down Too

            When ever there are two or more rule-sets being extended there is a chance of having 2 or more rules that conflict with one another. In fact, its almost a guarantee when start extending 3 or 4 rule-sets. This problem is solved creating a hierarchy based on the order that the rule-sets where placed in the .eslintrc.json file's "extends" field. Rules can only be configured once, so when two rule-sets attempt to configure them, the rule-set that is at the top of the hierarchy will have its configuration applied to the rule, all other rule-sets attempting to configure the rule will be disregarded by ESLint for the rule in conflict (and only for the rule in conflict). The hierarchy is based on the order that the extends field extends the rule sets, so its a very linear, military style hierarchy. In the US military the Lieutenant gives the Sergent orders, the Sergent gives orders to the privates. It is a linear chain of command.

    The following demonstrates how extending the rule-sets works when it comes to rule-conflicts:
    "extends": ["Top priority", "2nd priority", "Has no priority"]

    You can see that when 3 rule-sets are extended, the first rule-set is prioritized over the other two, and the 3rd rule-set has no priority.



    Her is a good example:


    "We will use a made up rule to demonstrate any arbitrary rule will work in this case, and; any mechanics that the rules implements doesn't change any of the information that I have outlined bellow."
    • Lets say that there's a rule called "no-understating-jD3VS-awesomeness"

    • And lets say that this rule is a base ESLint rule, you don't need a plugin to have access to it. It is always available.

    • Now lets say you add the following to your .eslintrc.json's "extends" field

         "extends": [
           "eslint:recommended", 
           "plugin:@angular-eslint/recommended", 
           "plugin:@typescript-eslint/recommended"
         ]
      


    Consider that the Following is True for Each Labeled Rule-set


    • "eslint:recommended" sets the following:
        "rules": {
          "no-understating-jD3VS-awesomeness": "error"
        }
      

    • "plugin:@angular-eslint/recommended" sets the following:
        "rules": {
          "no-understating-jD3VS-awesomeness": "off"
        }
      

    • "plugin:@typescript-eslint/recommended" sets the following:
        "rules": {
          "no-understating-jD3VS-awesomeness": "error"
        }
      


    Considering that everything stated under the words "for example" is true:

    "no-understating-jDEVS-awesomeness" will be set to "error" because the extended rule-set "eslint:recommended" was placed first in the extends array.

    Lets say we moved "eslint:recommended", such that the extended field looks like this:

       "extends": [
         "plugin:@angular-eslint/recommended", 
         "plugin:@typescript-eslint/recommended"
         "eslint:recommended", 
       ]
    

    in this case, "no-understating-jDEVS-awesomeness" would be disabled (aka set to "off") because now "plugin:@angular-eslint/recommended" takes precedence over the other rule-sets.





    There is reason for prioritizing certain rule-sets

    At this point in the discussion it should be obvious that when you are configuring the extends field you need to be conscious of where each rule-set is placed.

    As stated in this excerpts label,

    "there is good reason for prioritizing specific rule-sets".

    Generally speaking (of course there are rare exceptions), you will want plug-in rule-sets to over-ride rule-sets that configure the native ESLint rules. So if you were to use eslint:recommended and @typescript-eslint/plugin:recommended, you would one to add the later first (@typescript-eslint/plugin:recommended) because it changes how some of the eslint rules work, such that eslint will work with TS. If you did it the other way around, you would override the "ts-eslint/plugin" rule-set, with eslint rules, which would totally defeat the entire purpose of installing the "ts-eslint/plugin" in the first place.



    Rule-sets Containing Rule-sets


    Now, as far as asking if plugin:@angular-eslint/recommended contains "plugin:@typescript-eslint/recommended", the answer to this can be found in The Packages Repo. From the look of it, it converts the older (now deprecated) TSLint rules, to ESLint/Angular rules. This probably as gave his package TS support since before the TypeScript/ESLint plugin was first released.

    The short answer is, no it doesn't.

    For future reference though, the question you asked is a good question, because I am pretty sure that when you extend a rule-set that is simply a list of ESLint-rules, that it can't extend other Rule-sets, however, when the Rule-set is a rule-set from an ESLint-Plugin, then the Plugin can build-into the rules from other plug-ins, so the very well can be extended in such a case.


    ONE FINAL NOTE:

    Its important that you are aware, there is also the ESLint-Config-Angular repository, which I believe also extends a rule-set for the ESLint/Angular plugin. Just make sure you don't get them mixed up with the rule-set you are extending (which is the plugin at the link I shared a couple paragraphs up).

    I haven't seen the repos yet,


    Hopefully that all makes sense.