Skip to content

Instantly share code, notes, and snippets.

@dipiash
Created March 13, 2023 21:45
Show Gist options
  • Save dipiash/a5e78b20af18849fdff888c5820c44f7 to your computer and use it in GitHub Desktop.
Save dipiash/a5e78b20af18849fdff888c5820c44f7 to your computer and use it in GitHub Desktop.
ESLint (shared config)

Required modules

{
  "eslint": ">= 8.35.0",
  "@typescript-eslint/eslint-plugin": "^5.54.0",
  "@typescript-eslint/parser": "^5.54.0",
  "eslint-config-prettier": "^8.6.0",
  "eslint-import-resolver-typescript": "^3.5.3",
  "eslint-plugin-import": "^2.27.5",
  "eslint-plugin-jsx-a11y": "^6.7.1",
  "eslint-plugin-prettier": "^4.2.1",
  "eslint-plugin-promise": "^6.1.1",
  "eslint-plugin-react": "^7.32.2",
  "eslint-plugin-react-hooks": "^4.6.0",
  "eslint-plugin-simple-import-sort": "^10.0.0",
  "eslint-plugin-sonarjs": "^0.18.0",
  "eslint-plugin-storybook": "^0.6.11",
  "eslint-plugin-testing-library": "^5.10.2",
  "eslint-plugin-unicorn": "^45.0.2"
}

How to use

{
  "files": ["*.ts", "*.tsx"],
  "extends": [
    "eslint-config-shared-YOUR_PROJECT_TITLE" // or paste config from above
  ]
}
module.exports = {
"extends": [
"eslint:recommended",
"plugin:@nrwl/nx/typescript",
"prettier",
"plugin:prettier/recommended",
"plugin:jsx-a11y/recommended",
"plugin:promise/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:sonarjs/recommended",
"plugin:unicorn/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:testing-library/react"
],
"plugins": [
"react",
"react-hooks",
"sonarjs",
"unicorn",
"@typescript-eslint",
"prettier",
"promise",
"import",
"simple-import-sort"
],
"rules": {
"curly": ["error", "all"],
"prettier/prettier": "error",
"react/prop-types": "off",
"simple-import-sort/imports": [
"error",
{
"groups": [
// builtins modules
[
"^(events|fs|buffer|assert|child_process|cluster|dgram|dns|domain|crypto|http|https|module|net|console|constants|os|path|punycode|url|util|vm|zlib|async_hooks|freelist|v8|process|tls|tty|http2|perf_hooks|querystring|readline|repl|stream|string_decoder|sys|timers)(/.*|$)"
],
// react -> apollo -> other packages starts from @**
["^react", "^@apollo", "^@?\\w"],
// monorepo packages
["^(@YOUR_MONOREPO_PARENT_TITLE)(/.*|$)"],
// type files
["^.+?[Tt]ype.+?"],
// hooks
["^.*use[A-Z].*$"],
// side effect imports
["^\\u0000"],
// parent imports
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
// relative imports
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
// style
["^.*styled.(ts|tsx)$", "^.*css$"],
// icons
["^.*svg$"]
]
}
],
"simple-import-sort/exports": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error",
"import/prefer-default-export": "off",
"import/no-anonymous-default-export": [
"error",
{
"allowArray": false,
"allowArrowFunction": false,
"allowAnonymousClass": false,
"allowAnonymousFunction": false,
"allowCallExpression": true,
"allowLiteral": false,
"allowObject": true
}
],
"unicorn/no-array-reduce": "off",
"unicorn/prefer-module": "off",
"unicorn/no-empty-file": "off",
"unicorn/no-null": "off",
"unicorn/no-useless-undefined": "off",
"unicorn/filename-case": [
"error",
{
"cases": {
"pascalCase": true,
"camelCase": true
},
"ignore": [
"next-env.d.ts",
"vite(st)?.config.ts",
"vite-environment.d.ts",
"\\.spec.ts(x)?",
"\\.types.ts(x)?",
"\\.stories.ts(x)?",
"\\.styled.ts(x)?"
]
}
],
"unicorn/prevent-abbreviations": [
"error",
{
"checkFilenames": false
}
],
"padding-line-between-statements": [
"error",
{"blankLine": "always", "prev": ["const", "let", "var"], "next": "*"},
{"blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]},
{"blankLine": "always", "prev": "*", "next": "return"}
],
"no-multiple-empty-lines": ["error"],
"arrow-body-style": "off",
"prefer-arrow-callback": "off",
"no-console": ["error", {"allow": ["warn", "info", "error"]}],
"@typescript-eslint/no-use-before-define": ["error"],
"@typescript-eslint/no-unused-vars": [
"error"
],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "interface",
"format": ["PascalCase"],
"custom": {
"regex": "[A-Za-z]Interface$",
"match": true
}
},
{
"selector": "typeAlias",
"format": ["PascalCase"],
"custom": {
"regex": "[A-Za-z]Type$",
"match": true
}
}
],
"promise/prefer-await-to-then": "off",
"promise/always-return": "off",
"promise/catch-or-return": [2, { "allowThen": true, "allowFinally": true }],
"no-underscore-dangle": [
"error",
{
"allow": ["_id", "__typename", "__schema", "__dirname", "_global"],
"allowAfterThis": true
}
],
"sonarjs/no-identical-functions": ["error", 5],
"react-hooks/exhaustive-deps": [2],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
// un-ban a type that's banned by default
"{}": false
},
"extendDefaults": true
}
]
}
}
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "node_modules/**"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["@mantine/form", "@mantine/core"],
"message": "Please use import from @YOUR_PROJECT_TITLE/uikit"
}, {
"group": ["@mantine/utils"],
"message": "Please use import from @YOUR_PROJECT_TITLE/helpers"
},{
"group": ["@tanstack/react-query"],
"message": "Please use import from @YOUR_PROJECT_TITLE/rest"
}, {
"group": ["@tanstack/react-table"],
"message": "Please use import from @YOUR_PROJECT_TITLE/uikit"
}, {
"group": ["@tanstack/table-core"],
"message": "Please use import from @YOUR_PROJECT_TITLE/uikit"
}]
}]
},
"parserOptions": {
"project": ["tsconfig.*?.json"]
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment