Skip to content

Commit

Permalink
M2-5381: Add functional ESLint rules
Browse files Browse the repository at this point in the history
These rules are meant to be limited to the following categories:
- Potential Bugs Detection: Rules that help identify common coding mistakes that could lead to runtime errors or unexpected behavior.

- Performance Issues: Rules focused on optimizing performance, such as detecting unnecessary re-renders in React components or inefficient database queries.

- Stale Code Identification: Rules to detect unused variables, functions, components, or other elements that can clutter the codebase and reduce maintainability.

- Security Vulnerabilities: Basic security linting rules that flag potentially unsafe coding practices, such as improper handling of user input.
  • Loading branch information
sultanofcardio committed Feb 22, 2024
1 parent 280c215 commit 4d0b9f6
Show file tree
Hide file tree
Showing 5 changed files with 973 additions and 349 deletions.
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@
!/*.ts
!/*.tsx

# Except for the ESLint & Prettier configs. We can ignore those
.eslintrc.js
.prettierrc.js

# This looks like a generated file
src/entities/flanker/ui/HtmlFlanker/visual-stimulus-response.html
162 changes: 122 additions & 40 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,133 @@
module.exports = {
root: true,
extends: '@react-native-community',
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'import'],
parser: '@babel/eslint-parser',
extends: [
'eslint:recommended',
'@react-native-community',
'plugin:react/recommended',
'prettier'
],
plugins: ['import', 'react', 'react-hooks', 'unused-imports', 'jest'],
rules: {
'react/react-in-jsx-scope': 'off',
'react/jsx-newline': [2, { prevent: true, allowMultilines: true }],
'import/order': [
'error',
{
groups: [
['external', 'builtin'],
'internal',
['sibling', 'parent'],
'index',
],
pathGroups: [
{
pattern: '@(react|react-native)',
group: 'external',
position: 'before',
},
{
pattern:
'@(@app|@shared|@features|@screens|@entities|@assets|@jobs|@widgets)/**',
group: 'internal',
},
{
pattern: '@(@images)',
group: 'internal',
position: 'after',
},
],
pathGroupsExcludedImportTypes: ['internal', 'react'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'react-hooks/rules-of-hooks': 'warn',
'import/no-cycle': 'warn',
'constructor-super': 'warn',
'no-var': 'warn',
'no-caller': 'warn',
'array-callback-return': 'warn',
'no-eval': 'warn',
'no-extend-native': 'warn',
eqeqeq: ['warn', 'always'],
'no-script-url': 'warn',
'no-self-compare': 'warn',
'no-sequences': 'warn',
'no-nested-ternary': 'warn',
'no-unneeded-ternary': 'warn',
'no-debugger': 'warn',
'no-empty': 'warn',
'no-unused-labels': 'warn',
'prefer-const': 'warn',

// Required for unused-imports
'no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
'react-hooks/exhaustive-deps': 'warn',
'no-case-declarations': 'warn',
'no-unsafe-optional-chaining': 'warn',
'react/prop-types': 'warn',
'react/jsx-key': 'warn',
'react/jsx-no-duplicate-props': 'warn',
'react/jsx-no-target-blank': 'warn',
'react/jsx-no-undef': 'warn',
'react/no-danger-with-children': 'warn',
'react/no-deprecated': 'warn',
'react/no-direct-mutation-state': 'warn',
'react/no-find-dom-node': 'warn',
'react/no-is-mounted': 'warn',
'react/no-unescaped-entities': 'warn',
'react/no-unknown-property': 'warn',
'react/no-unsafe': 'warn',
'react/require-render-return': 'warn',
'react/display-name': 'off',
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
},
plugins: ['@typescript-eslint'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'prettier',
],
rules: {
'@typescript-eslint/no-shadow': ['error'],
'no-shadow': 'off',
'no-undef': 'off',
'react/react-in-jsx-scope': 'off',
'react/jsx-newline': [2, { prevent: true, allowMultilines: true }],
'import/order': [
'error',
{
groups: [
['external', 'builtin'],
'internal',
['sibling', 'parent'],
'index',
],
pathGroups: [
{
pattern: '@(react|react-native)',
group: 'external',
position: 'before',
},
{
pattern:
'@(@app|@shared|@features|@screens|@entities|@assets|@jobs|@widgets)/**',
group: 'internal',
},
{
pattern: '@(@images)',
group: 'internal',
position: 'after',
},
],
pathGroupsExcludedImportTypes: ['internal', 'react'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'@typescript-eslint/no-shadow': ['error'],
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-duplicate-enum-values': 'warn',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/no-unsafe-call': 'warn',
'@typescript-eslint/require-await': 'warn',
'@typescript-eslint/no-misused-promises': 'warn',
'@typescript-eslint/await-thenable': 'warn',
'@typescript-eslint/unbound-method': 'warn',
'@typescript-eslint/restrict-plus-operands': 'warn',
'@typescript-eslint/no-unsafe-return': 'warn',
'@typescript-eslint/restrict-template-expressions': 'warn',
'@typescript-eslint/no-unused-vars': 'off',
},
},
],
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
!/*.js
!/*.ts

# Except for the ESLint config itself. We can ignore that
.eslintrc.js

# This looks like a generated file
src/entities/flanker/ui/HtmlFlanker/visual-stimulus-response.html
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"start": "react-native start",
"test": "jest --noStackTrace",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:check": "yarn lint",
"lint:fix": "yarn lint --fix",
"pods": "bundle exec pod install --project-directory=ios",
"prepare": "husky install",
"postinstall": "yarn patch-package && react-native setup-ios-permissions",
Expand Down Expand Up @@ -119,9 +121,10 @@
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/eslint-parser": "^7.23.10",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^2.0.0",
"@react-native-community/eslint-config": "^3.2.0",
"@tsconfig/react-native": "^2.0.2",
"@types/jest": "^29.5.3",
"@types/markdown-it-container": "^2.0.5",
Expand All @@ -138,12 +141,19 @@
"babel-jest": "^29.6.2",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
"eslint": "^7.32.0",
"eslint": "^8.50.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-only-warn": "^1.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unused-imports": "^3.0.0",
"husky": "^8.0.0",
"jest": "^29.6.2",
"lint-staged": "^13.1.0",
"metro-react-native-babel-preset": "0.72.3",
"prettier": "^3.2.5",
"react-native-flipper": "0.182.0",
"react-query-native-devtools": "^4.0.0",
"react-test-renderer": "18.1.0",
Expand Down
Loading

0 comments on commit 4d0b9f6

Please sign in to comment.