1.1.0 • Published 1 year ago

eslint-config-citron v1.1.0

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

Eslint config Citron

Citron definition of beauty.

Philosophy

You will suffer, you will hate, but at the end you will pray the norm.

Patere legem quam ipse fecisti

Why impose a standard?

A programming standard is a game changer for long term project with multiple developers for two main reasons :

  1. It format and standardise the code so that anyone can read and understand easily and rapidly.
  2. It guide you in writing short and simple code.

How apply a standard?

The most important thing, no matter what your preferred javascript style is, is to be consistent when working with a team or a large codebase that will have to be maintained in the future.

Understand each rules and not try to hack them. Theses conventions are set to push you to write cleaner code.

These rules are not cast in stone, question them, discuss them around you, this is the best way to understand and improve this standard.

Getting started

Setup EsLint

  • First install eslint and eslint-config-citron
    npm i -D eslint eslint-config-citron
  • Then create your .eslintrc.json and extend with eslint-config-citron

    {
      "env": {
        "es2021": true,
    
        // If front (javascript)
        "browser": true,
    
        // If back (nodejs)
        "node": true
      },
    
      "extends": ["eslint-config-citron"]
    }

    For more information on eslint config see https://eslint.org/docs/user-guide/configuring/

  • Add EsLint to your IDE

Setup Prettier

  • First install prettier dependency
    npm i -D --save-exact prettier
  • Then create your .prettierrc.json with this configuration :
    {
      "trailingComma": "all",
      "tabWidth": 2,
      "useTabs": false,
      "semi": true,
      "singleQuote": true,
      "printWidth": 80
    }
  • Add prettier to your IDE

Code styling rules

Citron config

Citron has its own configuration which can be found here :

gads-citron/eslint-config-citron

This configuration is based on 3 majors standards :

Airbnb JavaScript Style Guide

airbnb/javascript

TypeScript ESLint

typescript-eslint/typescript-eslint

With theses two sets of rules :

Prettier

Prettier · Opinionated Code Formatter

We recommend to have looked to theses code styling rules.

Citron rules

max-lines

Maximum number of lines per file set to 150. Keep the code readable, force to split and organise your code

max-lines-per-function

Maximum number of lines per function set to 25. You will hate it Keep the code readable, force to split and organise your code

max-depth

Maximum block depth set to 4. Keep the code readable

  • Example

    // Bad
    function foo() {
      for (;;) {
        // Nested 1 deep
        while (true) {
          // Nested 2 deep
          if (true) {
            // Nested 3 deep
            if (true) {
              // Nested 4 deep
              if (true) {
                // Nested 5 deep
              }
            }
          }
        }
      }
    }
    
    // Good
    function foo() {
      for (;;) {
        // Nested 1 deep
        while (true) {
          // Nested 2 deep
          if (true) {
            // Nested 3 deep
            if (true) {
              // Nested 4 deep
            }
          }
        }
      }
    }

max-params

Maximum number of parameters allowed in function definitions set to 3. Keep the code readable

  • Example

    // Bad (4 params)
    function foo(bar, baz, qux, qxx) {
      doSomething();
    }
    
    // Good (3 params)
    function foo(bar, baz, qux) {
      doSomething();
    }

max-nested-callbacks

Maximum depth that callbacks set to 3. Keep the code readable

  • Example

    // Bad
    foo1(function () {
      foo2(function () {
        foo3(function () {
          foo4(function () {
            // Do something
          });
        });
      });
    });
    
    // Good
    foo1(function () {
      foo2(function () {
        foo3(function () {
          // Do something
        });
      });
    });

complexity

Maximum cyclomatic complexity set to 10. Cyclomatic complexity is the number of decisions or path an algorithm can make.
Reducing code complexity.

  • Example

    // Bad
    function a(x) {
      if (x === 1) {
        return x;
      } else if (x === 2) {
        return x - 1;
      } else if (x === 3) {
        return x - 23;
      } else if (x === 4) {
        return x + 9;
      } else if (x === 5) {
        return x + 42;
      } else if (x === 6) {
        return x + 42;
      } else if (x === 7) {
        return x + 42;
      } else if (x === 8) {
        return x + 42;
      } else if (x === 9) {
        return x + 42;
      } else if (x === 10) {
        return x + 42;
      } else {
        return 4; // 11 path
      }
    }
    
    // Good
    function a(x) {
      if (x === 1) {
        return x;
      } else if (x === 2) {
        return x - 1;
      } else if (x === 3) {
        return x - 23;
      } else if (x === 4) {
        return x + 9;
      } else {
        return 4; // 5 path
      }
    }

import/extensions

Omit the file extension only for typescript files (.ts). To avoid confusion on import.

  • Example Given the following folder structure:
    ├── user
    │   ├── user.model.ts
    │   ├── user.database.json
    The import statement will be :
    import { User } from './user/user.model';
    import users from './user/user.database.json';

import/no-default-export

Only named export are accepted. Name are consistent throughout all files.

  • Example

    // Bad
    const foo = 'bar';
    export default foo;
    
    // Good
    export const foo = 'bar';

@typescript-eslint/no-explicit-any

This rule doesn't allow any types to be defined. Using the any type defeats the purpose of using TypeScript.

  • Example

    // Bad
    const toto: any = 'toto';
    
    // Good
    const toto: string = 'toto';

Disabled rules

  • no-underscore-dangle
  • no-restricted-syntax This rule only apply on LabeledStatement and WithStatement
  • @typescript-eslint/no-misused-promises This rule only apply on checksConditionals

  • no-await-in-loop
    Can be dangerous, force to use Promise.All on too large arrays.

  • no-use-before-define - Only for functions
    For more clarity, allow use of function before definition.

    In a file, where a function or a class is export who use others functions define in this file but not exported, those unexported functions can be define after the exported one for more clarity so when the file is open, the main exported function/class is shown in first.

  • no-useless-constructor
    Allows dependency injections into classes with empty constructors.

Ressources