@rashedmakkouk/eslint-config
TypeScript icon, indicating that this package has built-in type declarations

0.8.6 • Public • Published

ESLint Config

npm (scoped with tag) ecmascript-version-supported

Opinionated linting rules providing a standardized developer experience across projects.

v0.8.0

This package has gone through an overhaul and v0.8.0 introduces many changes, including:

  • New plugins support.
  • Added/enabled new linting rules.
  • Removed previously set rules custom overrides.
  • Better support for TypeScript source code including stricter rules.
  • Updated peer dependencies.
  • And more, see What's Included section for details.

These changes will most likely output new errors and warnings in your project(s) codebase that will need to be updated/refactored.

This README file has been updated with the latest changes along with configuration examples.

Installation

Install the package in your project.

# NPM
npm install @rashedmakkouk/eslint-config --dev

# Yarn
yarn add @rashedmakkouk/eslint-config --dev

Configuration

For consistency, all configuration files use '.json' file extension.

ESLint

Add .eslintrc.json file to the root of your project, or to each of your packages if you are working on a monorepo, and add the following configuration:

.eslintrc.json

{
  "extends": [
    ...
    /**
    * If you already have a .eslintrc.* file, add this line to the end of the list if you want to
    * override preceding configurations.
    */
    "@rashedmakkouk/eslint-config"
  ],
  /**
    * ESLint looks for configuration files in successive parent directories all the way up to the
    * root directory of the filesystem (/). See 'Cascading and Hierarchy' for more details.
    * https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy
    *
    * To prevent this behavior, set 'root' property to true in your root project directory. This
    * tells ESLint to stop looking for other configuration files when it reaches this directory.
    *
    * If you are using this package in a monorepo, see 'Monorepos' for more details.
    * https://typescript-eslint.io/linting/typed-linting/monorepos
    */
  "root": true
}

Supported File Extensions

This package supports both JavaScript and TypeScript file extensions by default:

  • .js
  • .ts

React

If you are using React in your project, this package supports JSX file extensions by default:

  • .jsx
  • .tsx

To Enable JSX syntax support, add the following configuration:

.eslintrc.json

{
  ...
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true // Add this.
    }
  }
}

If you use eslint-plugin-react, add the following configuration:

.eslintrc.json

{
  ...
  "settings": {
    "react": {
      "version": "detect" // Add this.
    }
  }
}

Node.js

This package can be used in back-end Node.js projects out-of-the-box.

You may also want to install and configure eslint-plugin-node for language-specific rules, then add the following configuration:

.eslintrc.json

{
  ...
  "extends": [
    "plugin:node/recommended", // Add this.
    "@rashedmakkouk/eslint-config"
  ]
}

Other Frameworks

If you use other frameworks in your project like eslint-plugin-vue or eslint-plugin-svelte, you can add custom file extensions support after installing and configuring respective plugin as follows:

.eslintrc.json

{
  ...
  "extraFileExtensions": [".vue"],
  ...
}

See Using Plugins section below for more details.

Ignored Patterns

Ignored file and directory patterns from scanning and linting:

{
  "ignorePatterns": [
    "**/node_modules",
    "**/build",
    "**/dist"
  ]
}

Customizing Base Configuration

If you want to customize part of the base configuration, you can do so by adding respective property. Some example configuration:

.eslintrc.json

{
  ...
  "parserOptions": {
    /**
     * Refer to 'ECMAScript' badge at the top of this document for the latest
     * supported version by this package.
     */
    "ecmaVersion": "latest", // Or specify a number version (e.g. 2020).
    "ecmaFeatures": {
      "arrowFunctions": true
    }
  },
  "env": {
    "browser": true, // Default: false.
    "es6": true, // Default: true.
    "node": true // Default: true.
  },
  "ignorePatterns": [
    "**/node_modules"
    "**/scripts"
    "**/lib"
    ...
  ]
}

See ESLint Specifying Parser Options official documentation for the full list of available options.

Using Plugins

You can add other linting plugins that are not part of this package to your project and extend custom rules:

.eslintrc.json

{
  ...
  "plugins": [
    ...
    "custom-plugin" // Add plugins.
  ],
  "extends": [
    ...
    "plugin:custom/recommended", // Add rules.
    "@rashedmakkouk/eslint-config"
  ]
}

See ESLint Use a plugin and the plugin's official documentation for installation instructions.

Configuring Rules

Overriding Existing Rules

It is possible to customize options of linting rules applied by default with this package, you can add the rules you want to change under overrides property. Some example overrides:

.eslintrc.json

{
  ...
  "overrides": [
    ...
    {
      "files": ["*"],
      "rules": {
        /** Add and configure rules you want to override in all files. */
        "sort-vars": [ "warn", { "ignoreCase": true } ]
      }
    },
    {
      /** Specify file patterns to apply rule(s) to. */
      "files": ["*.jsx"],
      "rules": {
        "react/prop-types": "off",
      }
    }
  ]
}

See ESLint Configuring Rules official documentation for more details.

Extending New Rules

There are many rules provided by the Included Plugins that are part of this package but not Enabled, you can extend and enable specific rules you want in your project. See the official documentation of the plugin you want to extend for a complete list of available rules.

Usage with TypeScript

The recommended pattern is to create a new config file tsconfig.eslint.json and extend your base tsconfig.json file. This allows you to include file and directory patterns that are not supposed to be part of the main configuration file or should not be compiled, but you still want to apply the same linting standards to (e.g. scripts).

tsconfig.eslint.json

{
  "extends": "./tsconfig.json", // Or './tsconfig.base.json'.
  "compilerOptions": {
    /** Prevent using this file for a build. */
    "noEmit": true
  },
  /**
   * This configuration overrides 'includes' property in your base tsconfig file, make sure to list
   * all file and directory patterns you want to lint.
   */
  "include": [
    "**/scripts",
    "src/**/*",
    ...
  ]
}

If you choose to opt out of this pattern, tsconfig.json file will be loaded instead; see Supported File Patterns section below.

Supported File Patterns

This package supports loading the following tsconfig file patterns:

  • tsconfig.json (scanned and loaded by both ESLint 'parser' and 'import/resolver' plugin)
  • tsconfig.eslint.json (scanned and loaded only by ESLint 'parser')

Supported Directory Patterns

Directory patterns support both standard and monorepo projects and look for tsconfig files in:

  • root/
  • packages/*/
  • libs/*/
  • apps/*/
  • docs/

TSConfig (Reference)

TypeScript compiler options may be extended to set default values from a base configuration file. This package provides such file that you can extend, and override any project-specific configuration depending on your project needs.

Add the following configuration to the top of your project's tsconfig.json file:

tsconfig.json

{
  "extends": "@rashedmakkouk/eslint-config/lib/bases/tsconfig.base.json"
}

The base configuration set:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "tsconfig Recommended",
  "compilerOptions": {
    "module": "commonjs",
    "declaration": false,
    "sourceMap": false,
    "removeComments": false,
    "noEmit": false,
    "isolatedModules": false,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "noEmitOnError": true,
    "skipLibCheck": true,
    "experimentalDecorators": true,
    "types": [
      "node"
    ]
  }
}

Usage

Command Line Interface (Options)

To run ESLint from the command line, use the following command pattern:

npx eslint [options] [file|dir|glob]*

Some basic command usage examples:

# Find errors and warnings in multiple files in a directory.
#
# If you are on Microsoft Windows, wrap "src/**" with quotes to use node 'glob' syntax.
npx eslint src/**

# Find errors and warnings in specific file extensions.
npx eslint --ext .jsx,.js libs/

# Fix errors and warnings in file(s).
npx eslint --fix src/file1.js libs/file2.js

You can also use your package manager such as 'Yarn' or 'pnpm' to run commands, see respective official documentation for usage details.

See ESLint Command Line Interface official documentation for more in-depth usage information.

Editor Integration

Visual Studio Code

Before you begin, it is recommended that you use a Workspace Settings or a User Settings configuration file to apply the needed settings, it helps with portability and with committing the file as part of your repository. This section will focus on Workspace configuration steps.

You can get a copy of code-workspace.base.json file provided with this package from bases directory that you can use out-of-the-box. Make sure to rename the file to your-project.code-workspace.

Turn on auto-fix option only for needed providers to avoid overrides and/or unexpected results.

eslint

Static code analysis (auto-fix support).

  1. Install dbaeumer.vscode-eslint extension from VS Marketplace.

  2. Add the following configuration to VS Code Settings to turn on auto-fix for ESLint provider:

project.code-workspace

{
  ...
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}
  1. Configure ESLint extension behavior:

project.code-workspace

{
  ...
  "eslint.run": "onType", // Options: onType, onSave.
  "eslint.alwaysShowStatus": true,
  "eslint.packageManager": "yarn", // Options: yarn, npm.
  /**
   * Also accepts array of string paths you want to apply rules to.
   * Example: [ "./src", "./libs/client" ]
   */
  "eslint.workingDirectories": [
    {
      "mode": "location", // Options: location, auto.
      "pattern": "./src/*/" // Optional: A glob pattern to match a working directory.
    }
  ],
  "eslint.validate": [
    "typescript",
    "typescriptreact",
    "javascript",
    "javascriptreact"
  ],
  "eslint.options": {
    "extensions": [
      ".ts",
      ".tsx",
      ".js",
      ".jsx"
    ]
  }
}
prettier

Code styling and formatting (auto-fix support).

Defined rules and the linting process are part of ESLint main configuration, you do not need to install any additional extensions or make any changes to enable this plugin.

markdownlint

Markdown/CommonMark style checker and linting (auto-fix support).

  1. Install DavidAnson.vscode-markdownlint extension from VS Marketplace.

  2. Add .markdownlint.json file to the root of your project and add the following configuration:

.markdownlint.json

{
  "extends": "@rashedmakkouk/eslint-config/lib/bases/.markdownlint.base.json"
}
  1. Add the following configuration to VS Code Settings to turn on auto-fix for Markdownlint provider:
{
  "editor.codeActionsOnSave": {
    ...
    "source.fixAll.markdownlint": true
  }
}
cspell

Basic spell checker to help catch common spelling errors.

  1. Install streetsidesoftware.code-spell-checker extension from VS Marketplace.

  2. Add cspell.json file to the root of your project and add the following configuration:

cspell.json

{
  "words": [
    /** Add words you want to be ignored and not reported as 'Unknown word'. */
    "ignore-word"
  ]
}
tsdoc

TypeScript comments standards.

  1. Defined rules and the linting process are part of ESLint main configuration, you do not need to install any additional extensions to enable this plugin.

  2. Add .tsdoc.json file to the root of your project and add the following configuration:

tsdoc.json

{
  "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
  "extends": ["@rashedmakkouk/eslint-config/lib/bases/tsdoc.base.json"]
}

What's Included

Included Plugins

Plugins configured out-of-the-box:

{
  "plugins": [
    "@typescript-eslint",
    "eslint-plugin-tsdoc",
    "simple-import-sort",
    "import",
    "deprecation"
  ]
}

Included Rules

Rules extended out-of-the-box:

{
  "extends": [
    "eslint:recommended",
    "plugin:promise/recommended",
    "plugin:import/recommended",
    "plugin:import/typescript",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "plugin:prettier/recommended"
  ]
}

@typescript-eslint/strict (Rules)

Select rules are extended from @typescript-eslint/strict set that can be helpful in recommending best practice alternatives:

{
  "rules": {
    "@typescript-eslint/prefer-for-of": "error",
    "@typescript-eslint/prefer-includes": "error",
    "@typescript-eslint/prefer-string-starts-ends-with": "error",
    "@typescript-eslint/prefer-ts-expect-error": "error",
    "@typescript-eslint/no-throw-literal": [
      "error",
      {
        "allowThrowingAny": true,
        "allowThrowingUnknown": true
      }
    ],
    "@typescript-eslint/no-useless-constructor": "error"
  }
}

@typescript-eslint/naming-convention (Options)

Naming convention standards applied:

{
  "rules": {
    "@typescript-eslint/naming-convention": [
      "error",
      {
        "format": ["camelCase", "snake_case", "UPPER_CASE"],
        "leadingUnderscore": "allow",
        "selector": "variable",
        "trailingUnderscore": "forbid"
      },
      {
        "format": null,
        "modifiers": ["destructured"],
        "selector": "variable"
      },
      {
        "format": ["camelCase"],
        "leadingUnderscore": "forbid",
        "selector": "parameter",
        "trailingUnderscore": "forbid"
      },
      {
        "format": ["StrictPascalCase"],
        "selector": "typeLike"
      },
      {
        "custom": {
          "match": false,
          "regex": "^I[A-Z]"
        },
        "format": ["StrictPascalCase"],
        "selector": "interface"
      },
      {
        "format": ["StrictPascalCase"],
        "selector": "typeParameter",
        "suffix": ["T"]
      },
      {
        "format": ["StrictPascalCase"],
        "leadingUnderscore": "forbid",
        "selector": "class",
        "trailingUnderscore": "forbid"
      },
      {
        "format": ["camelCase"],
        "leadingUnderscore": "allow",
        "selector": "function",
        "trailingUnderscore": "forbid"
      },
    ]
  }
}

prettier/prettier (Options)

Styling and formatting rules applied:

{
  "rules": {
    ...
    "prettier/prettier": [
      "warn",
      {
        "arrowParens": "always",
        "bracketSpacing": true,
        "endOfLine": "auto",
        "insertPragma": false,
        "printWidth": 80,
        "proseWrap": "preserve",
        /** https://prettier.io/docs/en/options.html#require-pragma */
        "requirePragma": false,
        "semi": true,
        "singleQuote": true,
        /** Indent formatting. */
        "tabWidth": 2,
        "trailingComma": "es5"
      }
    ]
  }
}

Turned Off Rules

A few rules are turned off intentionally by this package to provide flexibility and freedom to use other available alternatives:

{
  "rules": {
    /** Interface naming for brevity, may simply extend other interfaces. */
    "@typescript-eslint/no-empty-interface": "off",
    /**
     * Disabled in favor of a more explicit and granular rule:
     * @typescript-eslint/naming-convention
     * https://typescript-eslint.io/rules/naming-convention
     */
    "camelcase": "off",
    /** Avoid false positives when using Bracket notation. */
    "dot-notation": "off",
    /** Suppress errors and warnings when importing from external packages. */
    "import/named": "off",
    /** Suppress errors and warnings when importing from external packages. */
    "import/namespace": "off",
    /** Suppress errors and warnings when importing from external packages. */
    "import/no-named-as-default": "off",
    "no-async-promise-executor": "off"
  }
}

FAQ

None of those TSConfigs include this file

This happens when TypeScript tries to parse a file not part of your project's tsconfig 'include' property.

An easy fix is to add the file where the error is reported to your project's tsconfig.json or tsconfig.eslint.json file.

See Usage with TypeScript for recommendations and best practices.

Also check Troubleshooting and FAQ official documentation for more information on this and other issues.

You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser

This can happen when ESLint TypeScript parser fails to load a 'tsconfig.json' file inside your project directory, particularly in a monorepo project.

To fix this issue, add the following configuration to your '.eslintrc.*' file:

{
  "parserOptions": {
    "project": ["./tsconfig.json"] // Add this.
  }
}

What does --fix-dry-run supposed to do

In short, the npx eslint --fix-dry-run option is mostly for integrations via stdin.

See the full explanation here #15668.

Community

Head over to Discussions where you can ask questions, request to add support for new plugins or voice your ideas and suggestions.

If you discover a bug and/or have an enhancement proposition for existing code, Issues is the place to go.

License

This package is available under the BSD 3-Clause license. It also includes external libraries that are available under a variety of licenses. See LICENSE for the full license text.

Dependencies (20)

Dev Dependencies (4)

Package Sidebar

Install

npm i @rashedmakkouk/eslint-config

Weekly Downloads

1

Version

0.8.6

License

BSD 3-Clause

Unpacked Size

59 kB

Total Files

13

Last publish

Collaborators

  • rashedmakkouk