From d4e7d00949f1f7c6064280f67d61b1ca30da1c28 Mon Sep 17 00:00:00 2001 From: Marcel Canhisares Date: Sun, 7 Apr 2024 23:27:13 -0400 Subject: [PATCH 1/4] Updating eslint packages to flat file --- packages/eslint-config-react-native/index.js | 611 +++++++++--------- .../eslint-config-react-native/package.json | 4 +- packages/eslint-plugin-react-native/index.js | 7 +- 3 files changed, 317 insertions(+), 305 deletions(-) diff --git a/packages/eslint-config-react-native/index.js b/packages/eslint-config-react-native/index.js index 97c4e93a25f16d..f569be266299a3 100644 --- a/packages/eslint-config-react-native/index.js +++ b/packages/eslint-config-react-native/index.js @@ -7,334 +7,343 @@ * @format */ -module.exports = { - env: { - es6: true, - }, +const eslintComments = require('eslint-plugin-eslint-comments'); +const react = require('eslint-plugin-react'); +const reactHooks = require('eslint-plugin-react-hooks'); +const reactNative = require('eslint-plugin-react-native'); +const reactNativeCommunity = require('@react-native/eslint-plugin'); +const jest = require('eslint-plugin-jest'); +const ftFlow = require('eslint-plugin-ft-flow'); +const babelParser = require('@babel/eslint-parser'); +const prettier = require('eslint-config-prettier'); +const typescriptParser = require('@typescript-eslint/parser'); +const typescriptPlugin = require('@typescript-eslint/eslint-plugin'); - parserOptions: { - sourceType: 'module', - ecmaFeatures: { - jsx: true, +module.exports = [ + prettier, + { + files: ['*.js'], + languageOptions: { + parser: babelParser, }, - }, - - extends: ['prettier'], - - plugins: [ - 'eslint-comments', - 'react', - 'react-hooks', - 'react-native', - '@react-native', - 'jest', - ], - - settings: { - react: { - version: 'detect', + plugins: { + 'ft-flow': ftFlow, + }, + rules: { + // Flow Plugin + // The following rules are made available via `eslint-plugin-ft-flow` + 'ft-flow/define-flow-type': 1, + 'ft-flow/use-flow-type': 1, }, }, - - overrides: [ - { - files: ['*.js'], - parser: '@babel/eslint-parser', - plugins: ['ft-flow'], - rules: { - // Flow Plugin - // The following rules are made available via `eslint-plugin-ft-flow` - - 'ft-flow/define-flow-type': 1, - 'ft-flow/use-flow-type': 1, - }, + { + files: ['*.jsx'], + languageOptions: { + parser: babelParser, }, - { - files: ['*.jsx'], - parser: '@babel/eslint-parser', + }, + { + files: ['*.ts', '*.tsx'], + languageOptions: { + parser: typescriptParser, }, - { - files: ['*.ts', '*.tsx'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint/eslint-plugin'], - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - }, - ], - 'no-unused-vars': 'off', - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 1, - 'no-undef': 'off', - 'func-call-spacing': 'off', - '@typescript-eslint/func-call-spacing': 1, - }, + plugins: { + '@typescript-eslint': typescriptPlugin, }, - { - files: [ - '*.{spec,test}.{js,ts,tsx}', - '**/__{mocks,tests}__/**/*.{js,ts,tsx}', + rules: { + '@typescript-eslint/no-shadow': 1, + '@typescript-eslint/func-call-spacing': 1, + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, ], - env: { - jest: true, - 'jest/globals': true, + 'no-unused-vars': 'off', + 'no-shadow': 'off', + 'no-undef': 'off', + 'func-call-spacing': 'off', + }, + }, + { + files: [ + '*.{spec,test}.{js,ts,tsx}', + '**/__{mocks,tests}__/**/*.{js,ts,tsx}', + ], + rules: { + 'react-native/no-inline-styles': 0, + quotes: [1, 'single', {avoidEscape: true, allowTemplateLiterals: true}], + }, + }, + { + plugins: { + 'eslint-comments': eslintComments, + react, + 'react-hooks': reactHooks, + 'react-native': reactNative, + '@react-native': reactNativeCommunity, + jest, + }, + languageOptions: { + sourceType: 'module', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + __DEV__: true, + __dirname: false, + __fbBatchedBridgeConfig: false, + AbortController: false, + Blob: true, + alert: false, + cancelAnimationFrame: false, + cancelIdleCallback: false, + clearImmediate: true, + clearInterval: false, + clearTimeout: false, + console: false, + document: false, + ErrorUtils: false, + escape: false, + Event: false, + EventTarget: false, + exports: false, + fetch: false, + File: true, + FileReader: false, + FormData: false, + global: false, + Headers: false, + Intl: false, + Map: true, + module: false, + navigator: false, + process: false, + Promise: true, + requestAnimationFrame: true, + requestIdleCallback: true, + require: false, + Set: true, + setImmediate: true, + setInterval: false, + setTimeout: false, + queueMicrotask: true, + URL: false, + URLSearchParams: false, + WebSocket: true, + window: false, + XMLHttpRequest: false, }, - rules: { - 'react-native/no-inline-styles': 0, - quotes: [1, 'single', {avoidEscape: true, allowTemplateLiterals: true}], + }, + settings: { + react: { + version: 'detect', }, }, - ], - // Map from global var to bool specifying if it can be redefined - globals: { - __DEV__: true, - __dirname: false, - __fbBatchedBridgeConfig: false, - AbortController: false, - Blob: true, - alert: false, - cancelAnimationFrame: false, - cancelIdleCallback: false, - clearImmediate: true, - clearInterval: false, - clearTimeout: false, - console: false, - document: false, - ErrorUtils: false, - escape: false, - Event: false, - EventTarget: false, - exports: false, - fetch: false, - File: true, - FileReader: false, - FormData: false, - global: false, - Headers: false, - Intl: false, - Map: true, - module: false, - navigator: false, - process: false, - Promise: true, - requestAnimationFrame: true, - requestIdleCallback: true, - require: false, - Set: true, - setImmediate: true, - setInterval: false, - setTimeout: false, - queueMicrotask: true, - URL: false, - URLSearchParams: false, - WebSocket: true, - window: false, - XMLHttpRequest: false, - }, + rules: { + // General + 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas + 'no-cond-assign': 1, // disallow assignment in conditional expressions + 'no-console': 0, // disallow use of console (off by default in the node environment) + 'no-const-assign': 2, // disallow assignment to const-declared variables + 'no-constant-condition': 0, // disallow use of constant expressions in conditions + 'no-control-regex': 1, // disallow control characters in regular expressions + 'no-debugger': 1, // disallow use of debugger + 'no-dupe-class-members': 2, // Disallow duplicate name in class members + 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals + 'no-empty': 0, // disallow empty statements + 'no-ex-assign': 1, // disallow assigning to the exception in a catch block + 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context + 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) + 'no-extra-semi': 1, // disallow unnecessary semicolons + 'no-func-assign': 1, // disallow overwriting functions written as function declarations + 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks + 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor + 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression + 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions + 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal + 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) + 'no-sparse-arrays': 1, // disallow sparse arrays + 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement + 'use-isnan': 1, // disallow comparisons with the value NaN + 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) + 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string - rules: { - // General - 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas - 'no-cond-assign': 1, // disallow assignment in conditional expressions - 'no-console': 0, // disallow use of console (off by default in the node environment) - 'no-const-assign': 2, // disallow assignment to const-declared variables - 'no-constant-condition': 0, // disallow use of constant expressions in conditions - 'no-control-regex': 1, // disallow control characters in regular expressions - 'no-debugger': 1, // disallow use of debugger - 'no-dupe-class-members': 2, // Disallow duplicate name in class members - 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals - 'no-empty': 0, // disallow empty statements - 'no-ex-assign': 1, // disallow assigning to the exception in a catch block - 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context - 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) - 'no-extra-semi': 1, // disallow unnecessary semicolons - 'no-func-assign': 1, // disallow overwriting functions written as function declarations - 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks - 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor - 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression - 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions - 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal - 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) - 'no-sparse-arrays': 1, // disallow sparse arrays - 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement - 'use-isnan': 1, // disallow comparisons with the value NaN - 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) - 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string + // Best Practices + // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. - // Best Practices - // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. + 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) + complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) + 'consistent-return': 0, // require return statements to either always or never specify values + curly: 1, // specify curly brace conventions for all control statements + 'default-case': 0, // require default case in switch statements (off by default) + 'dot-notation': 1, // encourages use of dot notation whenever possible + eqeqeq: [1, 'allow-null'], // require the use of === and !== + 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) + 'no-alert': 1, // disallow the use of alert, confirm, and prompt + 'no-caller': 1, // disallow use of arguments.caller or arguments.callee + 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) + 'no-else-return': 0, // disallow else after a return in an if (off by default) + 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) + 'no-eval': 2, // disallow use of eval() + 'no-extend-native': 1, // disallow adding to native types + 'no-extra-bind': 1, // disallow unnecessary function binding + 'no-fallthrough': 1, // disallow fallthrough of case statements + 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) + 'no-implied-eval': 1, // disallow use of eval()-like methods + 'no-labels': 1, // disallow use of labeled statements + 'no-iterator': 1, // disallow usage of __iterator__ property + 'no-lone-blocks': 1, // disallow unnecessary nested blocks + 'no-loop-func': 0, // disallow creation of functions within loops + 'no-multi-str': 0, // disallow use of multiline strings + 'no-native-reassign': 0, // disallow reassignments of native objects + 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison + 'no-new-func': 2, // disallow use of new operator for Function object + 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean + 'no-octal': 1, // disallow use of octal literals + 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + 'no-proto': 1, // disallow usage of __proto__ property + 'no-redeclare': 0, // disallow declaring the same variable more then once + 'no-return-assign': 1, // disallow use of assignment in return statement + 'no-script-url': 1, // disallow use of javascript: urls. + 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) + 'no-sequences': 1, // disallow use of comma operator + 'no-unused-expressions': 0, // disallow usage of expressions in statement position + 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals + 'no-void': 1, // disallow use of void operator (off by default) + 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) + 'no-with': 1, // disallow use of the with statement + radix: 1, // require use of the second argument for parseInt() (off by default) + 'semi-spacing': 1, // require a space after a semi-colon + 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) + 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) + yoda: 1, // require or disallow Yoda conditions - 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) - complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) - 'consistent-return': 0, // require return statements to either always or never specify values - curly: 1, // specify curly brace conventions for all control statements - 'default-case': 0, // require default case in switch statements (off by default) - 'dot-notation': 1, // encourages use of dot notation whenever possible - eqeqeq: [1, 'allow-null'], // require the use of === and !== - 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) - 'no-alert': 1, // disallow the use of alert, confirm, and prompt - 'no-caller': 1, // disallow use of arguments.caller or arguments.callee - 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) - 'no-else-return': 0, // disallow else after a return in an if (off by default) - 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) - 'no-eval': 2, // disallow use of eval() - 'no-extend-native': 1, // disallow adding to native types - 'no-extra-bind': 1, // disallow unnecessary function binding - 'no-fallthrough': 1, // disallow fallthrough of case statements - 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) - 'no-implied-eval': 1, // disallow use of eval()-like methods - 'no-labels': 1, // disallow use of labeled statements - 'no-iterator': 1, // disallow usage of __iterator__ property - 'no-lone-blocks': 1, // disallow unnecessary nested blocks - 'no-loop-func': 0, // disallow creation of functions within loops - 'no-multi-str': 0, // disallow use of multiline strings - 'no-native-reassign': 0, // disallow reassignments of native objects - 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison - 'no-new-func': 2, // disallow use of new operator for Function object - 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean - 'no-octal': 1, // disallow use of octal literals - 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; - 'no-proto': 1, // disallow usage of __proto__ property - 'no-redeclare': 0, // disallow declaring the same variable more then once - 'no-return-assign': 1, // disallow use of assignment in return statement - 'no-script-url': 1, // disallow use of javascript: urls. - 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) - 'no-sequences': 1, // disallow use of comma operator - 'no-unused-expressions': 0, // disallow usage of expressions in statement position - 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals - 'no-void': 1, // disallow use of void operator (off by default) - 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) - 'no-with': 1, // disallow use of the with statement - radix: 1, // require use of the second argument for parseInt() (off by default) - 'semi-spacing': 1, // require a space after a semi-colon - 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) - 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) - yoda: 1, // require or disallow Yoda conditions + // Variables + // These rules have to do with variable declarations. - // Variables - // These rules have to do with variable declarations. + 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + 'no-delete-var': 1, // disallow deletion of variables + 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables + 'no-label-var': 1, // disallow labels that share a name with a variable + 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope + 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments + 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block + 'no-undefined': 0, // disallow use of undefined variable (off by default) + 'no-undef-init': 1, // disallow use of undefined when initializing variables + 'no-unused-vars': [ + 1, + {vars: 'all', args: 'none', ignoreRestSiblings: true}, + ], // disallow declaration of variables that are not used in the code + 'no-use-before-define': 0, // disallow use of variables before they are defined - 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) - 'no-delete-var': 1, // disallow deletion of variables - 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables - 'no-label-var': 1, // disallow labels that share a name with a variable - 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope - 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments - 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block - 'no-undefined': 0, // disallow use of undefined variable (off by default) - 'no-undef-init': 1, // disallow use of undefined when initializing variables - 'no-unused-vars': [ - 1, - {vars: 'all', args: 'none', ignoreRestSiblings: true}, - ], // disallow declaration of variables that are not used in the code - 'no-use-before-define': 0, // disallow use of variables before they are defined + // Node.js + // These rules are specific to JavaScript running on Node.js. - // Node.js - // These rules are specific to JavaScript running on Node.js. + 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) + 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) + 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) + 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) + 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) + 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) + 'no-sync': 0, // disallow use of synchronous methods (off by default) - 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) - 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) - 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) - 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) - 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) - 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) - 'no-sync': 0, // disallow use of synchronous methods (off by default) + // ESLint Comments Plugin + // The following rules are made available via `eslint-plugin-eslint-comments` + 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments + 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names + 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors + 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled - // ESLint Comments Plugin - // The following rules are made available via `eslint-plugin-eslint-comments` - 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments - 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names - 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors - 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled + // Stylistic Issues + // These rules are purely matters of style and are quite subjective. - // Stylistic Issues - // These rules are purely matters of style and are quite subjective. + 'key-spacing': 0, + 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote + 'comma-spacing': 0, + 'no-multi-spaces': 0, + 'brace-style': 0, // enforce one true brace style (off by default) + camelcase: 0, // require camel case names + 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) + 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines + 'func-names': 0, // require function expressions to have a name (off by default) + 'func-style': 0, // enforces use of function declarations or expressions (off by default) + 'new-cap': 0, // require a capital letter for constructors + 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments + 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) + 'no-array-constructor': 1, // disallow use of the Array constructor + 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions + 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) + 'no-new-object': 1, // disallow use of the Object constructor + 'func-call-spacing': 1, // disallow space between function identifier and application + 'no-ternary': 0, // disallow the use of ternary operators (off by default) + 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines + 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers + 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation + quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used + 'quote-props': 0, // require quotes around object literal property names (off by default) + semi: 1, // require or disallow use of semicolons instead of ASI + 'sort-vars': 0, // sort variables within the same declaration block (off by default) + 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) + 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) + 'space-infix-ops': 1, // require spaces around operators + 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) + 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) + 'one-var': 0, // allow just one var statement per function (off by default) + 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) - 'key-spacing': 0, - 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote - 'comma-spacing': 0, - 'no-multi-spaces': 0, - 'brace-style': 0, // enforce one true brace style (off by default) - camelcase: 0, // require camel case names - 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) - 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines - 'func-names': 0, // require function expressions to have a name (off by default) - 'func-style': 0, // enforces use of function declarations or expressions (off by default) - 'new-cap': 0, // require a capital letter for constructors - 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments - 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) - 'no-array-constructor': 1, // disallow use of the Array constructor - 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions - 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) - 'no-new-object': 1, // disallow use of the Object constructor - 'func-call-spacing': 1, // disallow space between function identifier and application - 'no-ternary': 0, // disallow the use of ternary operators (off by default) - 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines - 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers - 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation - quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used - 'quote-props': 0, // require quotes around object literal property names (off by default) - semi: 1, // require or disallow use of semicolons instead of ASI - 'sort-vars': 0, // sort variables within the same declaration block (off by default) - 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) - 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) - 'space-infix-ops': 1, // require spaces around operators - 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) - 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) - 'one-var': 0, // allow just one var statement per function (off by default) - 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) + // Legacy + // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. - // Legacy - // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. + 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) + 'max-len': 0, // specify the maximum length of a line in your program (off by default) + 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) + 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) + 'no-bitwise': 1, // disallow use of bitwise operators (off by default) + 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) - 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) - 'max-len': 0, // specify the maximum length of a line in your program (off by default) - 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) - 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) - 'no-bitwise': 1, // disallow use of bitwise operators (off by default) - 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) + // React Plugin + // The following rules are made available via `eslint-plugin-react`. - // React Plugin - // The following rules are made available via `eslint-plugin-react`. + 'react/display-name': 0, + 'react/jsx-boolean-value': 0, + 'react/jsx-no-comment-textnodes': 2, + 'react/jsx-no-duplicate-props': 2, + 'react/jsx-no-undef': 2, + 'react/jsx-sort-props': 0, + 'react/jsx-uses-react': 1, + 'react/jsx-uses-vars': 1, + 'react/no-did-mount-set-state': 1, + 'react/no-did-update-set-state': 1, + 'react/no-multi-comp': 0, + 'react/no-string-refs': 2, + 'react/no-unknown-property': 0, + 'react/no-unstable-nested-components': 1, + 'react/prop-types': 0, + 'react/react-in-jsx-scope': 1, + 'react/self-closing-comp': 1, + 'react/wrap-multilines': 0, - 'react/display-name': 0, - 'react/jsx-boolean-value': 0, - 'react/jsx-no-comment-textnodes': 2, - 'react/jsx-no-duplicate-props': 2, - 'react/jsx-no-undef': 2, - 'react/jsx-sort-props': 0, - 'react/jsx-uses-react': 1, - 'react/jsx-uses-vars': 1, - 'react/no-did-mount-set-state': 1, - 'react/no-did-update-set-state': 1, - 'react/no-multi-comp': 0, - 'react/no-string-refs': 2, - 'react/no-unknown-property': 0, - 'react/no-unstable-nested-components': 1, - 'react/prop-types': 0, - 'react/react-in-jsx-scope': 1, - 'react/self-closing-comp': 1, - 'react/wrap-multilines': 0, + // React-Hooks Plugin + // The following rules are made available via `eslint-plugin-react-hooks` + 'react-hooks/rules-of-hooks': 2, + 'react-hooks/exhaustive-deps': 2, - // React-Hooks Plugin - // The following rules are made available via `eslint-plugin-react-hooks` - 'react-hooks/rules-of-hooks': 2, - 'react-hooks/exhaustive-deps': 2, + // React-Native Plugin + // The following rules are made available via `eslint-plugin-react-native` - // React-Native Plugin - // The following rules are made available via `eslint-plugin-react-native` + 'react-native/no-inline-styles': 1, - 'react-native/no-inline-styles': 1, - - // Jest Plugin - // The following rules are made available via `eslint-plugin-jest`. - 'jest/no-disabled-tests': 1, - 'jest/no-focused-tests': 1, - 'jest/no-identical-title': 1, - 'jest/valid-expect': 1, + // Jest Plugin + // The following rules are made available via `eslint-plugin-jest`. + 'jest/no-disabled-tests': 1, + 'jest/no-focused-tests': 1, + 'jest/no-identical-title': 1, + 'jest/valid-expect': 1, + }, }, -}; +]; diff --git a/packages/eslint-config-react-native/package.json b/packages/eslint-config-react-native/package.json index 157abcb425018f..08600343daf544 100644 --- a/packages/eslint-config-react-native/package.json +++ b/packages/eslint-config-react-native/package.json @@ -25,9 +25,9 @@ "@react-native/eslint-plugin": "0.76.0-main", "@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/parser": "^7.1.1", - "eslint-config-prettier": "^8.5.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-ft-flow": "^2.0.1", + "eslint-plugin-ft-flow": "^3.0.7", "eslint-plugin-jest": "^27.9.0", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/packages/eslint-plugin-react-native/index.js b/packages/eslint-plugin-react-native/index.js index 5c3756184557fd..3406f66708342a 100644 --- a/packages/eslint-plugin-react-native/index.js +++ b/packages/eslint-plugin-react-native/index.js @@ -7,6 +7,9 @@ * @format */ -exports.rules = { - 'platform-colors': require('./platform-colors'), + +module.exports = { + rules: { + 'platform-colors': require('./platform-colors'), + } }; From fa9fccd4385f577fce62fe5e88bafd7ba5e12abf Mon Sep 17 00:00:00 2001 From: Marcel Canhisares Date: Mon, 8 Apr 2024 16:54:21 -0400 Subject: [PATCH 2/4] Updating commented eslint flags, updating readme with more detailed instructions for flat config files --- packages/eslint-config-react-native/README.md | 32 ++++++++++++++++++- packages/eslint-config-react-native/index.js | 4 +-- packages/eslint-plugin-react-native/README.md | 17 +++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/packages/eslint-config-react-native/README.md b/packages/eslint-config-react-native/README.md index e8045d262cfb57..af2b114d64f313 100644 --- a/packages/eslint-config-react-native/README.md +++ b/packages/eslint-config-react-native/README.md @@ -2,6 +2,9 @@ [![Version][version-badge]][package] +## About +This plugin exports a recommended eslint config for React Native projects + ## Installation ``` @@ -12,7 +15,24 @@ yarn add --dev eslint prettier @react-native/eslint-config ## Usage -Add to your eslint config (`.eslintrc`, or `eslintConfig` field in `package.json`): +From [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0) onwards, you can use `eslint.config.js` which uses the new [flat config file format](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new). + +```javascript +const reactNativeConfig = require('@react-native/eslint-config'); +const myplugin = require('my-plugin'); + +module.exports = [ + ...reactNativeConfig, + { + plugins: { + myplugin + }, + ... + }, +]; +``` + +If you're still using a version of eslint < `v8.23.0` or still using the old configuration files, place the following on your eslint config file (`.eslintrc`, or `eslintConfig` field in `package.json`): ```json { @@ -20,5 +40,15 @@ Add to your eslint config (`.eslintrc`, or `eslintConfig` field in `package.json } ``` +## Plugin supported Eslint versions + +| Eslint version | `.eslintrc` support | `eslint.config.js` support | +| :------------------- | :-----------------: | :------------------------: | +| `>= 9.0.0` | ❌ | ❌ | +| `>= 8.23.0 < 9.0.0` | ✅ | ✅ | +| `< 8.23.0` | ✅ | ❌ | + + + [version-badge]: https://img.shields.io/npm/v/@react-native/eslint-config.svg?style=flat-square [package]: https://www.npmjs.com/package/@react-native/eslint-config diff --git a/packages/eslint-config-react-native/index.js b/packages/eslint-config-react-native/index.js index f569be266299a3..a46b2916fc3070 100644 --- a/packages/eslint-config-react-native/index.js +++ b/packages/eslint-config-react-native/index.js @@ -13,11 +13,11 @@ const reactHooks = require('eslint-plugin-react-hooks'); const reactNative = require('eslint-plugin-react-native'); const reactNativeCommunity = require('@react-native/eslint-plugin'); const jest = require('eslint-plugin-jest'); -const ftFlow = require('eslint-plugin-ft-flow'); const babelParser = require('@babel/eslint-parser'); const prettier = require('eslint-config-prettier'); const typescriptParser = require('@typescript-eslint/parser'); const typescriptPlugin = require('@typescript-eslint/eslint-plugin'); +const ftFlow = require('eslint-plugin-ft-flow'); module.exports = [ prettier, @@ -91,7 +91,7 @@ module.exports = [ ecmaFeatures: { jsx: true, }, - }, + }, globals: { __DEV__: true, __dirname: false, diff --git a/packages/eslint-plugin-react-native/README.md b/packages/eslint-plugin-react-native/README.md index 48fc9bcf67c1a0..7871cfd016891c 100644 --- a/packages/eslint-plugin-react-native/README.md +++ b/packages/eslint-plugin-react-native/README.md @@ -12,7 +12,22 @@ yarn add --dev eslint @react-native/eslint-plugin ## Usage -Add to your eslint config (`.eslintrc`, or `eslintConfig` field in `package.json`): +From [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0) onwards, you can use `eslint.config.js` which uses the new [flat config file format](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new). + +```javascript +const reactNative = require('@react-native/eslint-plugin'); + +module.exports = [ + { + plugins: { + reactNative + }, + ... + }, +]; +``` + +If you're still using a version of eslint < `v8.23.0` or still using the old configuration files, place the following on your eslint config file (`.eslintrc`, or `eslintConfig` field in `package.json`): ```json { From e2badfd334fa2ed122c5dba93fbb6e26e9d2a843 Mon Sep 17 00:00:00 2001 From: Marcel Canhisares Date: Wed, 14 Aug 2024 23:30:29 -0400 Subject: [PATCH 3/4] Migrating config to eslint plugin --- packages/eslint-config-react-native/index.js | 587 ++++++++++-------- packages/eslint-plugin-react-native/index.js | 436 ++++++++++++- .../eslint-plugin-react-native/package.json | 24 +- 3 files changed, 794 insertions(+), 253 deletions(-) diff --git a/packages/eslint-config-react-native/index.js b/packages/eslint-config-react-native/index.js index a46b2916fc3070..5a9a34b0742ae4 100644 --- a/packages/eslint-config-react-native/index.js +++ b/packages/eslint-config-react-native/index.js @@ -6,7 +6,6 @@ * * @format */ - const eslintComments = require('eslint-plugin-eslint-comments'); const react = require('eslint-plugin-react'); const reactHooks = require('eslint-plugin-react-hooks'); @@ -19,7 +18,341 @@ const typescriptParser = require('@typescript-eslint/parser'); const typescriptPlugin = require('@typescript-eslint/eslint-plugin'); const ftFlow = require('eslint-plugin-ft-flow'); -module.exports = [ +// Map from global var to bool specifying if it can be redefined +const globals = { + __DEV__: true, + __dirname: false, + __fbBatchedBridgeConfig: false, + AbortController: false, + Blob: true, + alert: false, + cancelAnimationFrame: false, + cancelIdleCallback: false, + clearImmediate: true, + clearInterval: false, + clearTimeout: false, + console: false, + document: false, + ErrorUtils: false, + escape: false, + Event: false, + EventTarget: false, + exports: false, + fetch: false, + File: true, + FileReader: false, + FormData: false, + global: false, + Headers: false, + Intl: false, + Map: true, + module: false, + navigator: false, + process: false, + Promise: true, + requestAnimationFrame: true, + requestIdleCallback: true, + require: false, + Set: true, + setImmediate: true, + setInterval: false, + setTimeout: false, + queueMicrotask: true, + URL: false, + URLSearchParams: false, + WebSocket: true, + window: false, + XMLHttpRequest: false, +}; + +const rules = { + // General + 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas + 'no-cond-assign': 1, // disallow assignment in conditional expressions + 'no-console': 0, // disallow use of console (off by default in the node environment) + 'no-const-assign': 2, // disallow assignment to const-declared variables + 'no-constant-condition': 0, // disallow use of constant expressions in conditions + 'no-control-regex': 1, // disallow control characters in regular expressions + 'no-debugger': 1, // disallow use of debugger + 'no-dupe-class-members': 2, // Disallow duplicate name in class members + 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals + 'no-empty': 0, // disallow empty statements + 'no-ex-assign': 1, // disallow assigning to the exception in a catch block + 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context + 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) + 'no-extra-semi': 1, // disallow unnecessary semicolons + 'no-func-assign': 1, // disallow overwriting functions written as function declarations + 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks + 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor + 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression + 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions + 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal + 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) + 'no-sparse-arrays': 1, // disallow sparse arrays + 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement + 'use-isnan': 1, // disallow comparisons with the value NaN + 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) + 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string + + // Best Practices + // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. + + 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) + complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) + 'consistent-return': 0, // require return statements to either always or never specify values + curly: 1, // specify curly brace conventions for all control statements + 'default-case': 0, // require default case in switch statements (off by default) + 'dot-notation': 1, // encourages use of dot notation whenever possible + eqeqeq: [1, 'allow-null'], // require the use of === and !== + 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) + 'no-alert': 1, // disallow the use of alert, confirm, and prompt + 'no-caller': 1, // disallow use of arguments.caller or arguments.callee + 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) + 'no-else-return': 0, // disallow else after a return in an if (off by default) + 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) + 'no-eval': 2, // disallow use of eval() + 'no-extend-native': 1, // disallow adding to native types + 'no-extra-bind': 1, // disallow unnecessary function binding + 'no-fallthrough': 1, // disallow fallthrough of case statements + 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) + 'no-implied-eval': 1, // disallow use of eval()-like methods + 'no-labels': 1, // disallow use of labeled statements + 'no-iterator': 1, // disallow usage of __iterator__ property + 'no-lone-blocks': 1, // disallow unnecessary nested blocks + 'no-loop-func': 0, // disallow creation of functions within loops + 'no-multi-str': 0, // disallow use of multiline strings + 'no-native-reassign': 0, // disallow reassignments of native objects + 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison + 'no-new-func': 2, // disallow use of new operator for Function object + 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean + 'no-octal': 1, // disallow use of octal literals + 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + 'no-proto': 1, // disallow usage of __proto__ property + 'no-redeclare': 0, // disallow declaring the same variable more then once + 'no-return-assign': 1, // disallow use of assignment in return statement + 'no-script-url': 1, // disallow use of javascript: urls. + 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) + 'no-sequences': 1, // disallow use of comma operator + 'no-unused-expressions': 0, // disallow usage of expressions in statement position + 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals + 'no-void': 1, // disallow use of void operator (off by default) + 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) + 'no-with': 1, // disallow use of the with statement + radix: 1, // require use of the second argument for parseInt() (off by default) + 'semi-spacing': 1, // require a space after a semi-colon + 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) + 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) + yoda: 1, // require or disallow Yoda conditions + + // Variables + // These rules have to do with variable declarations. + + 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + 'no-delete-var': 1, // disallow deletion of variables + 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables + 'no-label-var': 1, // disallow labels that share a name with a variable + 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope + 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments + 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block + 'no-undefined': 0, // disallow use of undefined variable (off by default) + 'no-undef-init': 1, // disallow use of undefined when initializing variables + 'no-unused-vars': [1, {vars: 'all', args: 'none', ignoreRestSiblings: true}], // disallow declaration of variables that are not used in the code + 'no-use-before-define': 0, // disallow use of variables before they are defined + + // Node.js + // These rules are specific to JavaScript running on Node.js. + + 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) + 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) + 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) + 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) + 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) + 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) + 'no-sync': 0, // disallow use of synchronous methods (off by default) + + // ESLint Comments Plugin + // The following rules are made available via `eslint-plugin-eslint-comments` + 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments + 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names + 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors + 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled + + // Stylistic Issues + // These rules are purely matters of style and are quite subjective. + + 'key-spacing': 0, + 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote + 'comma-spacing': 0, + 'no-multi-spaces': 0, + 'brace-style': 0, // enforce one true brace style (off by default) + camelcase: 0, // require camel case names + 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) + 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines + 'func-names': 0, // require function expressions to have a name (off by default) + 'func-style': 0, // enforces use of function declarations or expressions (off by default) + 'new-cap': 0, // require a capital letter for constructors + 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments + 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) + 'no-array-constructor': 1, // disallow use of the Array constructor + 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions + 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) + 'no-new-object': 1, // disallow use of the Object constructor + 'func-call-spacing': 1, // disallow space between function identifier and application + 'no-ternary': 0, // disallow the use of ternary operators (off by default) + 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines + 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers + 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation + quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used + 'quote-props': 0, // require quotes around object literal property names (off by default) + semi: 1, // require or disallow use of semicolons instead of ASI + 'sort-vars': 0, // sort variables within the same declaration block (off by default) + 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) + 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) + 'space-infix-ops': 1, // require spaces around operators + 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) + 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) + 'one-var': 0, // allow just one var statement per function (off by default) + 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) + + // Legacy + // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. + + 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) + 'max-len': 0, // specify the maximum length of a line in your program (off by default) + 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) + 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) + 'no-bitwise': 1, // disallow use of bitwise operators (off by default) + 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) + + // React Plugin + // The following rules are made available via `eslint-plugin-react`. + + 'react/display-name': 0, + 'react/jsx-boolean-value': 0, + 'react/jsx-no-comment-textnodes': 2, + 'react/jsx-no-duplicate-props': 2, + 'react/jsx-no-undef': 2, + 'react/jsx-sort-props': 0, + 'react/jsx-uses-react': 1, + 'react/jsx-uses-vars': 1, + 'react/no-did-mount-set-state': 1, + 'react/no-did-update-set-state': 1, + 'react/no-multi-comp': 0, + 'react/no-string-refs': 2, + 'react/no-unknown-property': 0, + 'react/no-unstable-nested-components': 1, + 'react/prop-types': 0, + 'react/react-in-jsx-scope': 1, + 'react/self-closing-comp': 1, + 'react/wrap-multilines': 0, + + // React-Hooks Plugin + // The following rules are made available via `eslint-plugin-react-hooks` + 'react-hooks/rules-of-hooks': 2, + 'react-hooks/exhaustive-deps': 2, + + // React-Native Plugin + // The following rules are made available via `eslint-plugin-react-native` + + 'react-native/no-inline-styles': 1, + + // Jest Plugin + // The following rules are made available via `eslint-plugin-jest`. + 'jest/no-disabled-tests': 1, + 'jest/no-focused-tests': 1, + 'jest/no-identical-title': 1, + 'jest/valid-expect': 1, +}; + +const plugin = { + configs: { + legacy: { + parserOptions: { + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + extends: ['plugin:prettier/recommended'], + + plugins: [ + 'eslint-comments', + 'react', + 'react-hooks', + 'react-native', + '@react-native', + 'jest', + ], + + settings: { + react: { + version: 'detect', + }, + }, + + overrides: [ + { + files: ['*.js'], + parser: '@babel/eslint-parser', + plugins: ['ft-flow'], + rules: { + // Flow Plugin + // The following rules are made available via `eslint-plugin-ft-flow` + + 'ft-flow/define-flow-type': 1, + 'ft-flow/use-flow-type': 1, + }, + }, + { + files: ['*.jsx'], + parser: '@babel/eslint-parser', + }, + { + files: ['*.ts', '*.tsx'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint/eslint-plugin'], + rules: { + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, + ], + 'no-unused-vars': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 1, + 'no-undef': 'off', + 'func-call-spacing': 'off', + '@typescript-eslint/func-call-spacing': 1, + }, + }, + { + files: [ + '*.{spec,test}.{js,ts,tsx}', + '**/__{mocks,tests}__/**/*.{js,ts,tsx}', + ], + env: { + jest: true, + 'jest/globals': true, + }, + rules: { + 'react-native/no-inline-styles': 0, + quotes: [ + 1, + 'single', + {avoidEscape: true, allowTemplateLiterals: true}, + ], + }, + }, + ], + globals: globals, + rules: rules, + }, + }, +}; + +plugin.configs.flat = [ prettier, { files: ['*.js'], @@ -92,51 +425,7 @@ module.exports = [ jsx: true, }, }, - globals: { - __DEV__: true, - __dirname: false, - __fbBatchedBridgeConfig: false, - AbortController: false, - Blob: true, - alert: false, - cancelAnimationFrame: false, - cancelIdleCallback: false, - clearImmediate: true, - clearInterval: false, - clearTimeout: false, - console: false, - document: false, - ErrorUtils: false, - escape: false, - Event: false, - EventTarget: false, - exports: false, - fetch: false, - File: true, - FileReader: false, - FormData: false, - global: false, - Headers: false, - Intl: false, - Map: true, - module: false, - navigator: false, - process: false, - Promise: true, - requestAnimationFrame: true, - requestIdleCallback: true, - require: false, - Set: true, - setImmediate: true, - setInterval: false, - setTimeout: false, - queueMicrotask: true, - URL: false, - URLSearchParams: false, - WebSocket: true, - window: false, - XMLHttpRequest: false, - }, + globals, }, settings: { react: { @@ -144,206 +433,8 @@ module.exports = [ }, }, - rules: { - // General - 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas - 'no-cond-assign': 1, // disallow assignment in conditional expressions - 'no-console': 0, // disallow use of console (off by default in the node environment) - 'no-const-assign': 2, // disallow assignment to const-declared variables - 'no-constant-condition': 0, // disallow use of constant expressions in conditions - 'no-control-regex': 1, // disallow control characters in regular expressions - 'no-debugger': 1, // disallow use of debugger - 'no-dupe-class-members': 2, // Disallow duplicate name in class members - 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals - 'no-empty': 0, // disallow empty statements - 'no-ex-assign': 1, // disallow assigning to the exception in a catch block - 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context - 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) - 'no-extra-semi': 1, // disallow unnecessary semicolons - 'no-func-assign': 1, // disallow overwriting functions written as function declarations - 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks - 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor - 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression - 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions - 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal - 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) - 'no-sparse-arrays': 1, // disallow sparse arrays - 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement - 'use-isnan': 1, // disallow comparisons with the value NaN - 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) - 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string - - // Best Practices - // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. - - 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) - complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) - 'consistent-return': 0, // require return statements to either always or never specify values - curly: 1, // specify curly brace conventions for all control statements - 'default-case': 0, // require default case in switch statements (off by default) - 'dot-notation': 1, // encourages use of dot notation whenever possible - eqeqeq: [1, 'allow-null'], // require the use of === and !== - 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) - 'no-alert': 1, // disallow the use of alert, confirm, and prompt - 'no-caller': 1, // disallow use of arguments.caller or arguments.callee - 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) - 'no-else-return': 0, // disallow else after a return in an if (off by default) - 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) - 'no-eval': 2, // disallow use of eval() - 'no-extend-native': 1, // disallow adding to native types - 'no-extra-bind': 1, // disallow unnecessary function binding - 'no-fallthrough': 1, // disallow fallthrough of case statements - 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) - 'no-implied-eval': 1, // disallow use of eval()-like methods - 'no-labels': 1, // disallow use of labeled statements - 'no-iterator': 1, // disallow usage of __iterator__ property - 'no-lone-blocks': 1, // disallow unnecessary nested blocks - 'no-loop-func': 0, // disallow creation of functions within loops - 'no-multi-str': 0, // disallow use of multiline strings - 'no-native-reassign': 0, // disallow reassignments of native objects - 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison - 'no-new-func': 2, // disallow use of new operator for Function object - 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean - 'no-octal': 1, // disallow use of octal literals - 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; - 'no-proto': 1, // disallow usage of __proto__ property - 'no-redeclare': 0, // disallow declaring the same variable more then once - 'no-return-assign': 1, // disallow use of assignment in return statement - 'no-script-url': 1, // disallow use of javascript: urls. - 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) - 'no-sequences': 1, // disallow use of comma operator - 'no-unused-expressions': 0, // disallow usage of expressions in statement position - 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals - 'no-void': 1, // disallow use of void operator (off by default) - 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) - 'no-with': 1, // disallow use of the with statement - radix: 1, // require use of the second argument for parseInt() (off by default) - 'semi-spacing': 1, // require a space after a semi-colon - 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) - 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) - yoda: 1, // require or disallow Yoda conditions - - // Variables - // These rules have to do with variable declarations. - - 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) - 'no-delete-var': 1, // disallow deletion of variables - 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables - 'no-label-var': 1, // disallow labels that share a name with a variable - 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope - 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments - 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block - 'no-undefined': 0, // disallow use of undefined variable (off by default) - 'no-undef-init': 1, // disallow use of undefined when initializing variables - 'no-unused-vars': [ - 1, - {vars: 'all', args: 'none', ignoreRestSiblings: true}, - ], // disallow declaration of variables that are not used in the code - 'no-use-before-define': 0, // disallow use of variables before they are defined - - // Node.js - // These rules are specific to JavaScript running on Node.js. - - 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) - 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) - 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) - 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) - 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) - 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) - 'no-sync': 0, // disallow use of synchronous methods (off by default) - - // ESLint Comments Plugin - // The following rules are made available via `eslint-plugin-eslint-comments` - 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments - 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names - 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors - 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled - - // Stylistic Issues - // These rules are purely matters of style and are quite subjective. - - 'key-spacing': 0, - 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote - 'comma-spacing': 0, - 'no-multi-spaces': 0, - 'brace-style': 0, // enforce one true brace style (off by default) - camelcase: 0, // require camel case names - 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) - 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines - 'func-names': 0, // require function expressions to have a name (off by default) - 'func-style': 0, // enforces use of function declarations or expressions (off by default) - 'new-cap': 0, // require a capital letter for constructors - 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments - 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) - 'no-array-constructor': 1, // disallow use of the Array constructor - 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions - 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) - 'no-new-object': 1, // disallow use of the Object constructor - 'func-call-spacing': 1, // disallow space between function identifier and application - 'no-ternary': 0, // disallow the use of ternary operators (off by default) - 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines - 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers - 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation - quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used - 'quote-props': 0, // require quotes around object literal property names (off by default) - semi: 1, // require or disallow use of semicolons instead of ASI - 'sort-vars': 0, // sort variables within the same declaration block (off by default) - 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) - 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) - 'space-infix-ops': 1, // require spaces around operators - 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) - 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) - 'one-var': 0, // allow just one var statement per function (off by default) - 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) - - // Legacy - // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. - - 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) - 'max-len': 0, // specify the maximum length of a line in your program (off by default) - 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) - 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) - 'no-bitwise': 1, // disallow use of bitwise operators (off by default) - 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) - - // React Plugin - // The following rules are made available via `eslint-plugin-react`. - - 'react/display-name': 0, - 'react/jsx-boolean-value': 0, - 'react/jsx-no-comment-textnodes': 2, - 'react/jsx-no-duplicate-props': 2, - 'react/jsx-no-undef': 2, - 'react/jsx-sort-props': 0, - 'react/jsx-uses-react': 1, - 'react/jsx-uses-vars': 1, - 'react/no-did-mount-set-state': 1, - 'react/no-did-update-set-state': 1, - 'react/no-multi-comp': 0, - 'react/no-string-refs': 2, - 'react/no-unknown-property': 0, - 'react/no-unstable-nested-components': 1, - 'react/prop-types': 0, - 'react/react-in-jsx-scope': 1, - 'react/self-closing-comp': 1, - 'react/wrap-multilines': 0, - - // React-Hooks Plugin - // The following rules are made available via `eslint-plugin-react-hooks` - 'react-hooks/rules-of-hooks': 2, - 'react-hooks/exhaustive-deps': 2, - - // React-Native Plugin - // The following rules are made available via `eslint-plugin-react-native` - - 'react-native/no-inline-styles': 1, - - // Jest Plugin - // The following rules are made available via `eslint-plugin-jest`. - 'jest/no-disabled-tests': 1, - 'jest/no-focused-tests': 1, - 'jest/no-identical-title': 1, - 'jest/valid-expect': 1, - }, + rules, }, ]; + +module.exports = plugin; diff --git a/packages/eslint-plugin-react-native/index.js b/packages/eslint-plugin-react-native/index.js index 3406f66708342a..ddcb68a0705fd2 100644 --- a/packages/eslint-plugin-react-native/index.js +++ b/packages/eslint-plugin-react-native/index.js @@ -6,10 +6,438 @@ * * @format */ +const eslintComments = require('eslint-plugin-eslint-comments'); +const react = require('eslint-plugin-react'); +const reactHooks = require('eslint-plugin-react-hooks'); +const reactNative = require('eslint-plugin-react-native'); +const reactNativeCommunity = require('@react-native/eslint-plugin'); +const jest = require('eslint-plugin-jest'); +const babelParser = require('@babel/eslint-parser'); +const prettier = require('eslint-config-prettier'); +const typescriptParser = require('@typescript-eslint/parser'); +const typescriptPlugin = require('@typescript-eslint/eslint-plugin'); +const ftFlow = require('eslint-plugin-ft-flow'); +// Map from global var to bool specifying if it can be redefined +const globals = { + __DEV__: true, + __dirname: false, + __fbBatchedBridgeConfig: false, + AbortController: false, + Blob: true, + alert: false, + cancelAnimationFrame: false, + cancelIdleCallback: false, + clearImmediate: true, + clearInterval: false, + clearTimeout: false, + console: false, + document: false, + ErrorUtils: false, + escape: false, + Event: false, + EventTarget: false, + exports: false, + fetch: false, + File: true, + FileReader: false, + FormData: false, + global: false, + Headers: false, + Intl: false, + Map: true, + module: false, + navigator: false, + process: false, + Promise: true, + requestAnimationFrame: true, + requestIdleCallback: true, + require: false, + Set: true, + setImmediate: true, + setInterval: false, + setTimeout: false, + queueMicrotask: true, + URL: false, + URLSearchParams: false, + WebSocket: true, + window: false, + XMLHttpRequest: false, +}; + +const rules = { + // Local Rules + 'platform-colors': require('./platform-colors'), + + // General + 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas + 'no-cond-assign': 1, // disallow assignment in conditional expressions + 'no-console': 0, // disallow use of console (off by default in the node environment) + 'no-const-assign': 2, // disallow assignment to const-declared variables + 'no-constant-condition': 0, // disallow use of constant expressions in conditions + 'no-control-regex': 1, // disallow control characters in regular expressions + 'no-debugger': 1, // disallow use of debugger + 'no-dupe-class-members': 2, // Disallow duplicate name in class members + 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals + 'no-empty': 0, // disallow empty statements + 'no-ex-assign': 1, // disallow assigning to the exception in a catch block + 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context + 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) + 'no-extra-semi': 1, // disallow unnecessary semicolons + 'no-func-assign': 1, // disallow overwriting functions written as function declarations + 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks + 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor + 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression + 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions + 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal + 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) + 'no-sparse-arrays': 1, // disallow sparse arrays + 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement + 'use-isnan': 1, // disallow comparisons with the value NaN + 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) + 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string + + // Best Practices + // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. + + 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) + complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) + 'consistent-return': 0, // require return statements to either always or never specify values + curly: 1, // specify curly brace conventions for all control statements + 'default-case': 0, // require default case in switch statements (off by default) + 'dot-notation': 1, // encourages use of dot notation whenever possible + eqeqeq: [1, 'allow-null'], // require the use of === and !== + 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) + 'no-alert': 1, // disallow the use of alert, confirm, and prompt + 'no-caller': 1, // disallow use of arguments.caller or arguments.callee + 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) + 'no-else-return': 0, // disallow else after a return in an if (off by default) + 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) + 'no-eval': 2, // disallow use of eval() + 'no-extend-native': 1, // disallow adding to native types + 'no-extra-bind': 1, // disallow unnecessary function binding + 'no-fallthrough': 1, // disallow fallthrough of case statements + 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) + 'no-implied-eval': 1, // disallow use of eval()-like methods + 'no-labels': 1, // disallow use of labeled statements + 'no-iterator': 1, // disallow usage of __iterator__ property + 'no-lone-blocks': 1, // disallow unnecessary nested blocks + 'no-loop-func': 0, // disallow creation of functions within loops + 'no-multi-str': 0, // disallow use of multiline strings + 'no-native-reassign': 0, // disallow reassignments of native objects + 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison + 'no-new-func': 2, // disallow use of new operator for Function object + 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean + 'no-octal': 1, // disallow use of octal literals + 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + 'no-proto': 1, // disallow usage of __proto__ property + 'no-redeclare': 0, // disallow declaring the same variable more then once + 'no-return-assign': 1, // disallow use of assignment in return statement + 'no-script-url': 1, // disallow use of javascript: urls. + 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) + 'no-sequences': 1, // disallow use of comma operator + 'no-unused-expressions': 0, // disallow usage of expressions in statement position + 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals + 'no-void': 1, // disallow use of void operator (off by default) + 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) + 'no-with': 1, // disallow use of the with statement + radix: 1, // require use of the second argument for parseInt() (off by default) + 'semi-spacing': 1, // require a space after a semi-colon + 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) + 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) + yoda: 1, // require or disallow Yoda conditions + + // Variables + // These rules have to do with variable declarations. + + 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + 'no-delete-var': 1, // disallow deletion of variables + 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables + 'no-label-var': 1, // disallow labels that share a name with a variable + 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope + 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments + 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block + 'no-undefined': 0, // disallow use of undefined variable (off by default) + 'no-undef-init': 1, // disallow use of undefined when initializing variables + 'no-unused-vars': [1, {vars: 'all', args: 'none', ignoreRestSiblings: true}], // disallow declaration of variables that are not used in the code + 'no-use-before-define': 0, // disallow use of variables before they are defined + + // Node.js + // These rules are specific to JavaScript running on Node.js. + + 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) + 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) + 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) + 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) + 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) + 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) + 'no-sync': 0, // disallow use of synchronous methods (off by default) + + // ESLint Comments Plugin + // The following rules are made available via `eslint-plugin-eslint-comments` + 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments + 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names + 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors + 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled + + // Stylistic Issues + // These rules are purely matters of style and are quite subjective. + + 'key-spacing': 0, + 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote + 'comma-spacing': 0, + 'no-multi-spaces': 0, + 'brace-style': 0, // enforce one true brace style (off by default) + camelcase: 0, // require camel case names + 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) + 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines + 'func-names': 0, // require function expressions to have a name (off by default) + 'func-style': 0, // enforces use of function declarations or expressions (off by default) + 'new-cap': 0, // require a capital letter for constructors + 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments + 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) + 'no-array-constructor': 1, // disallow use of the Array constructor + 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions + 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) + 'no-new-object': 1, // disallow use of the Object constructor + 'func-call-spacing': 1, // disallow space between function identifier and application + 'no-ternary': 0, // disallow the use of ternary operators (off by default) + 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines + 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers + 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation + quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used + 'quote-props': 0, // require quotes around object literal property names (off by default) + semi: 1, // require or disallow use of semicolons instead of ASI + 'sort-vars': 0, // sort variables within the same declaration block (off by default) + 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) + 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) + 'space-infix-ops': 1, // require spaces around operators + 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) + 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) + 'one-var': 0, // allow just one var statement per function (off by default) + 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) + + // Legacy + // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. + + 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) + 'max-len': 0, // specify the maximum length of a line in your program (off by default) + 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) + 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) + 'no-bitwise': 1, // disallow use of bitwise operators (off by default) + 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) -module.exports = { - rules: { - 'platform-colors': require('./platform-colors'), - } + // React Plugin + // The following rules are made available via `eslint-plugin-react`. + + 'react/display-name': 0, + 'react/jsx-boolean-value': 0, + 'react/jsx-no-comment-textnodes': 2, + 'react/jsx-no-duplicate-props': 2, + 'react/jsx-no-undef': 2, + 'react/jsx-sort-props': 0, + 'react/jsx-uses-react': 1, + 'react/jsx-uses-vars': 1, + 'react/no-did-mount-set-state': 1, + 'react/no-did-update-set-state': 1, + 'react/no-multi-comp': 0, + 'react/no-string-refs': 2, + 'react/no-unknown-property': 0, + 'react/no-unstable-nested-components': 1, + 'react/prop-types': 0, + 'react/react-in-jsx-scope': 1, + 'react/self-closing-comp': 1, + 'react/wrap-multilines': 0, + + // React-Hooks Plugin + // The following rules are made available via `eslint-plugin-react-hooks` + 'react-hooks/rules-of-hooks': 2, + 'react-hooks/exhaustive-deps': 2, + + // React-Native Plugin + // The following rules are made available via `eslint-plugin-react-native` + + 'react-native/no-inline-styles': 1, + + // Jest Plugin + // The following rules are made available via `eslint-plugin-jest`. + 'jest/no-disabled-tests': 1, + 'jest/no-focused-tests': 1, + 'jest/no-identical-title': 1, + 'jest/valid-expect': 1, +}; + +const plugin = { + configs: { + legacy: { + parserOptions: { + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + extends: ['plugin:prettier/recommended'], + + plugins: [ + 'eslint-comments', + 'react', + 'react-hooks', + 'react-native', + '@react-native', + 'jest', + ], + + settings: { + react: { + version: 'detect', + }, + }, + + overrides: [ + { + files: ['*.js'], + parser: '@babel/eslint-parser', + plugins: ['ft-flow'], + rules: { + // Flow Plugin + // The following rules are made available via `eslint-plugin-ft-flow` + + 'ft-flow/define-flow-type': 1, + 'ft-flow/use-flow-type': 1, + }, + }, + { + files: ['*.jsx'], + parser: '@babel/eslint-parser', + }, + { + files: ['*.ts', '*.tsx'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint/eslint-plugin'], + rules: { + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, + ], + 'no-unused-vars': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 1, + 'no-undef': 'off', + 'func-call-spacing': 'off', + '@typescript-eslint/func-call-spacing': 1, + }, + }, + { + files: [ + '*.{spec,test}.{js,ts,tsx}', + '**/__{mocks,tests}__/**/*.{js,ts,tsx}', + ], + env: { + jest: true, + 'jest/globals': true, + }, + rules: { + 'react-native/no-inline-styles': 0, + quotes: [ + 1, + 'single', + {avoidEscape: true, allowTemplateLiterals: true}, + ], + }, + }, + ], + globals: globals, + rules: rules, + }, + }, }; + +plugin.configs.flat = [ + prettier, + { + files: ['*.js'], + languageOptions: { + parser: babelParser, + }, + plugins: { + 'ft-flow': ftFlow, + }, + rules: { + // Flow Plugin + // The following rules are made available via `eslint-plugin-ft-flow` + 'ft-flow/define-flow-type': 1, + 'ft-flow/use-flow-type': 1, + }, + }, + { + files: ['*.jsx'], + languageOptions: { + parser: babelParser, + }, + }, + { + files: ['*.ts', '*.tsx'], + languageOptions: { + parser: typescriptParser, + }, + plugins: { + '@typescript-eslint': typescriptPlugin, + }, + rules: { + '@typescript-eslint/no-shadow': 1, + '@typescript-eslint/func-call-spacing': 1, + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, + ], + 'no-unused-vars': 'off', + 'no-shadow': 'off', + 'no-undef': 'off', + 'func-call-spacing': 'off', + }, + }, + { + files: [ + '*.{spec,test}.{js,ts,tsx}', + '**/__{mocks,tests}__/**/*.{js,ts,tsx}', + ], + rules: { + 'react-native/no-inline-styles': 0, + quotes: [1, 'single', {avoidEscape: true, allowTemplateLiterals: true}], + }, + }, + { + plugins: { + 'eslint-comments': eslintComments, + react, + 'react-hooks': reactHooks, + 'react-native': reactNative, + '@react-native': reactNativeCommunity, + jest, + }, + languageOptions: { + sourceType: 'module', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals, + }, + settings: { + react: { + version: 'detect', + }, + }, + + rules, + }, +]; + +module.exports = plugin; diff --git a/packages/eslint-plugin-react-native/package.json b/packages/eslint-plugin-react-native/package.json index b3031267048c79..97a999e09359bf 100644 --- a/packages/eslint-plugin-react-native/package.json +++ b/packages/eslint-plugin-react-native/package.json @@ -19,5 +19,27 @@ "engines": { "node": ">=18" }, - "main": "index.js" + "main": "index.js", + "dependencies": { + "@babel/core": "^7.20.0", + "@babel/eslint-parser": "^7.20.0", + "@react-native/eslint-plugin": "0.76.0-main", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-ft-flow": "^3.0.7", + "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-react": "^7.30.1", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-native": "^4.0.0" + }, + "peerDependencies": { + "eslint": ">=8", + "prettier": ">=2" + }, + "devDependencies": { + "eslint": "^8.57.0", + "prettier": "2.8.8" + } } From b2d73977350d33aea6002271cdbcb600bee6d3f0 Mon Sep 17 00:00:00 2001 From: Marcel Canhisares Date: Thu, 15 Aug 2024 00:53:14 -0400 Subject: [PATCH 4/4] Migrating config to eslint plugin --- packages/eslint-config-react-native/README.md | 54 --- packages/eslint-config-react-native/index.js | 440 ------------------ .../eslint-config-react-native/package.json | 44 -- packages/eslint-plugin-react-native/README.md | 54 ++- .../__tests__/platform-colors-test.js | 2 +- packages/eslint-plugin-react-native/index.js | 8 +- .../eslint-plugin-react-native/package.json | 3 +- .../eslint-plugin-react-native/rules/index.js | 8 + .../{ => rules}/platform-colors.js | 0 9 files changed, 65 insertions(+), 548 deletions(-) delete mode 100644 packages/eslint-config-react-native/README.md delete mode 100644 packages/eslint-config-react-native/index.js delete mode 100644 packages/eslint-config-react-native/package.json create mode 100644 packages/eslint-plugin-react-native/rules/index.js rename packages/eslint-plugin-react-native/{ => rules}/platform-colors.js (100%) diff --git a/packages/eslint-config-react-native/README.md b/packages/eslint-config-react-native/README.md deleted file mode 100644 index af2b114d64f313..00000000000000 --- a/packages/eslint-config-react-native/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# @react-native/eslint-config - -[![Version][version-badge]][package] - -## About -This plugin exports a recommended eslint config for React Native projects - -## Installation - -``` -yarn add --dev eslint prettier @react-native/eslint-config -``` - -*Note: We're using `yarn` to install deps. Feel free to change commands to use `npm` 3+ and `npx` if you like* - -## Usage - -From [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0) onwards, you can use `eslint.config.js` which uses the new [flat config file format](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new). - -```javascript -const reactNativeConfig = require('@react-native/eslint-config'); -const myplugin = require('my-plugin'); - -module.exports = [ - ...reactNativeConfig, - { - plugins: { - myplugin - }, - ... - }, -]; -``` - -If you're still using a version of eslint < `v8.23.0` or still using the old configuration files, place the following on your eslint config file (`.eslintrc`, or `eslintConfig` field in `package.json`): - -```json -{ - "extends": "@react-native" -} -``` - -## Plugin supported Eslint versions - -| Eslint version | `.eslintrc` support | `eslint.config.js` support | -| :------------------- | :-----------------: | :------------------------: | -| `>= 9.0.0` | ❌ | ❌ | -| `>= 8.23.0 < 9.0.0` | ✅ | ✅ | -| `< 8.23.0` | ✅ | ❌ | - - - -[version-badge]: https://img.shields.io/npm/v/@react-native/eslint-config.svg?style=flat-square -[package]: https://www.npmjs.com/package/@react-native/eslint-config diff --git a/packages/eslint-config-react-native/index.js b/packages/eslint-config-react-native/index.js deleted file mode 100644 index 5a9a34b0742ae4..00000000000000 --- a/packages/eslint-config-react-native/index.js +++ /dev/null @@ -1,440 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ -const eslintComments = require('eslint-plugin-eslint-comments'); -const react = require('eslint-plugin-react'); -const reactHooks = require('eslint-plugin-react-hooks'); -const reactNative = require('eslint-plugin-react-native'); -const reactNativeCommunity = require('@react-native/eslint-plugin'); -const jest = require('eslint-plugin-jest'); -const babelParser = require('@babel/eslint-parser'); -const prettier = require('eslint-config-prettier'); -const typescriptParser = require('@typescript-eslint/parser'); -const typescriptPlugin = require('@typescript-eslint/eslint-plugin'); -const ftFlow = require('eslint-plugin-ft-flow'); - -// Map from global var to bool specifying if it can be redefined -const globals = { - __DEV__: true, - __dirname: false, - __fbBatchedBridgeConfig: false, - AbortController: false, - Blob: true, - alert: false, - cancelAnimationFrame: false, - cancelIdleCallback: false, - clearImmediate: true, - clearInterval: false, - clearTimeout: false, - console: false, - document: false, - ErrorUtils: false, - escape: false, - Event: false, - EventTarget: false, - exports: false, - fetch: false, - File: true, - FileReader: false, - FormData: false, - global: false, - Headers: false, - Intl: false, - Map: true, - module: false, - navigator: false, - process: false, - Promise: true, - requestAnimationFrame: true, - requestIdleCallback: true, - require: false, - Set: true, - setImmediate: true, - setInterval: false, - setTimeout: false, - queueMicrotask: true, - URL: false, - URLSearchParams: false, - WebSocket: true, - window: false, - XMLHttpRequest: false, -}; - -const rules = { - // General - 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas - 'no-cond-assign': 1, // disallow assignment in conditional expressions - 'no-console': 0, // disallow use of console (off by default in the node environment) - 'no-const-assign': 2, // disallow assignment to const-declared variables - 'no-constant-condition': 0, // disallow use of constant expressions in conditions - 'no-control-regex': 1, // disallow control characters in regular expressions - 'no-debugger': 1, // disallow use of debugger - 'no-dupe-class-members': 2, // Disallow duplicate name in class members - 'no-dupe-keys': 2, // disallow duplicate keys when creating object literals - 'no-empty': 0, // disallow empty statements - 'no-ex-assign': 1, // disallow assigning to the exception in a catch block - 'no-extra-boolean-cast': 1, // disallow double-negation boolean casts in a boolean context - 'no-extra-parens': 0, // disallow unnecessary parentheses (off by default) - 'no-extra-semi': 1, // disallow unnecessary semicolons - 'no-func-assign': 1, // disallow overwriting functions written as function declarations - 'no-inner-declarations': 0, // disallow function or variable declarations in nested blocks - 'no-invalid-regexp': 1, // disallow invalid regular expression strings in the RegExp constructor - 'no-negated-in-lhs': 1, // disallow negation of the left operand of an in expression - 'no-obj-calls': 1, // disallow the use of object properties of the global object (Math and JSON) as functions - 'no-regex-spaces': 1, // disallow multiple spaces in a regular expression literal - 'no-reserved-keys': 0, // disallow reserved words being used as object literal keys (off by default) - 'no-sparse-arrays': 1, // disallow sparse arrays - 'no-unreachable': 2, // disallow unreachable statements after a return, throw, continue, or break statement - 'use-isnan': 1, // disallow comparisons with the value NaN - 'valid-jsdoc': 0, // Ensure JSDoc comments are valid (off by default) - 'valid-typeof': 1, // Ensure that the results of typeof are compared against a valid string - - // Best Practices - // These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns. - - 'block-scoped-var': 0, // treat var statements as if they were block scoped (off by default) - complexity: 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) - 'consistent-return': 0, // require return statements to either always or never specify values - curly: 1, // specify curly brace conventions for all control statements - 'default-case': 0, // require default case in switch statements (off by default) - 'dot-notation': 1, // encourages use of dot notation whenever possible - eqeqeq: [1, 'allow-null'], // require the use of === and !== - 'guard-for-in': 0, // make sure for-in loops have an if statement (off by default) - 'no-alert': 1, // disallow the use of alert, confirm, and prompt - 'no-caller': 1, // disallow use of arguments.caller or arguments.callee - 'no-div-regex': 1, // disallow division operators explicitly at beginning of regular expression (off by default) - 'no-else-return': 0, // disallow else after a return in an if (off by default) - 'no-eq-null': 0, // disallow comparisons to null without a type-checking operator (off by default) - 'no-eval': 2, // disallow use of eval() - 'no-extend-native': 1, // disallow adding to native types - 'no-extra-bind': 1, // disallow unnecessary function binding - 'no-fallthrough': 1, // disallow fallthrough of case statements - 'no-floating-decimal': 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default) - 'no-implied-eval': 1, // disallow use of eval()-like methods - 'no-labels': 1, // disallow use of labeled statements - 'no-iterator': 1, // disallow usage of __iterator__ property - 'no-lone-blocks': 1, // disallow unnecessary nested blocks - 'no-loop-func': 0, // disallow creation of functions within loops - 'no-multi-str': 0, // disallow use of multiline strings - 'no-native-reassign': 0, // disallow reassignments of native objects - 'no-new': 1, // disallow use of new operator when not part of the assignment or comparison - 'no-new-func': 2, // disallow use of new operator for Function object - 'no-new-wrappers': 1, // disallows creating new instances of String,Number, and Boolean - 'no-octal': 1, // disallow use of octal literals - 'no-octal-escape': 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; - 'no-proto': 1, // disallow usage of __proto__ property - 'no-redeclare': 0, // disallow declaring the same variable more then once - 'no-return-assign': 1, // disallow use of assignment in return statement - 'no-script-url': 1, // disallow use of javascript: urls. - 'no-self-compare': 1, // disallow comparisons where both sides are exactly the same (off by default) - 'no-sequences': 1, // disallow use of comma operator - 'no-unused-expressions': 0, // disallow usage of expressions in statement position - 'no-useless-escape': 1, // disallow escapes that don't have any effect in literals - 'no-void': 1, // disallow use of void operator (off by default) - 'no-warning-comments': 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default) - 'no-with': 1, // disallow use of the with statement - radix: 1, // require use of the second argument for parseInt() (off by default) - 'semi-spacing': 1, // require a space after a semi-colon - 'vars-on-top': 0, // requires to declare all vars on top of their containing scope (off by default) - 'wrap-iife': 0, // require immediate function invocation to be wrapped in parentheses (off by default) - yoda: 1, // require or disallow Yoda conditions - - // Variables - // These rules have to do with variable declarations. - - 'no-catch-shadow': 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) - 'no-delete-var': 1, // disallow deletion of variables - 'no-global-assign': 2, // disallow assignments to native objects or read-only global variables - 'no-label-var': 1, // disallow labels that share a name with a variable - 'no-shadow': 1, // disallow declaration of variables already declared in the outer scope - 'no-shadow-restricted-names': 1, // disallow shadowing of names such as arguments - 'no-undef': 2, // disallow use of undeclared variables unless mentioned in a /*global */ block - 'no-undefined': 0, // disallow use of undefined variable (off by default) - 'no-undef-init': 1, // disallow use of undefined when initializing variables - 'no-unused-vars': [1, {vars: 'all', args: 'none', ignoreRestSiblings: true}], // disallow declaration of variables that are not used in the code - 'no-use-before-define': 0, // disallow use of variables before they are defined - - // Node.js - // These rules are specific to JavaScript running on Node.js. - - 'handle-callback-err': 1, // enforces error handling in callbacks (off by default) (on by default in the node environment) - 'no-mixed-requires': 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) - 'no-new-require': 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment) - 'no-path-concat': 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) - 'no-process-exit': 0, // disallow process.exit() (on by default in the node environment) - 'no-restricted-modules': 1, // restrict usage of specified node modules (off by default) - 'no-sync': 0, // disallow use of synchronous methods (off by default) - - // ESLint Comments Plugin - // The following rules are made available via `eslint-plugin-eslint-comments` - 'eslint-comments/no-aggregating-enable': 1, // disallows eslint-enable comments for multiple eslint-disable comments - 'eslint-comments/no-unlimited-disable': 1, // disallows eslint-disable comments without rule names - 'eslint-comments/no-unused-disable': 1, // disallow disables that don't cover any errors - 'eslint-comments/no-unused-enable': 1, // // disallow enables that don't enable anything or enable rules that weren't disabled - - // Stylistic Issues - // These rules are purely matters of style and are quite subjective. - - 'key-spacing': 0, - 'jsx-quotes': [1, 'prefer-double'], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote - 'comma-spacing': 0, - 'no-multi-spaces': 0, - 'brace-style': 0, // enforce one true brace style (off by default) - camelcase: 0, // require camel case names - 'consistent-this': 1, // enforces consistent naming when capturing the current execution context (off by default) - 'eol-last': 1, // enforce newline at the end of file, with no multiple empty lines - 'func-names': 0, // require function expressions to have a name (off by default) - 'func-style': 0, // enforces use of function declarations or expressions (off by default) - 'new-cap': 0, // require a capital letter for constructors - 'new-parens': 1, // disallow the omission of parentheses when invoking a constructor with no arguments - 'no-nested-ternary': 0, // disallow nested ternary expressions (off by default) - 'no-array-constructor': 1, // disallow use of the Array constructor - 'no-empty-character-class': 1, // disallow the use of empty character classes in regular expressions - 'no-lonely-if': 0, // disallow if as the only statement in an else block (off by default) - 'no-new-object': 1, // disallow use of the Object constructor - 'func-call-spacing': 1, // disallow space between function identifier and application - 'no-ternary': 0, // disallow the use of ternary operators (off by default) - 'no-trailing-spaces': 1, // disallow trailing whitespace at the end of lines - 'no-underscore-dangle': 0, // disallow dangling underscores in identifiers - 'no-mixed-spaces-and-tabs': 1, // disallow mixed spaces and tabs for indentation - quotes: [1, 'single', 'avoid-escape'], // specify whether double or single quotes should be used - 'quote-props': 0, // require quotes around object literal property names (off by default) - semi: 1, // require or disallow use of semicolons instead of ASI - 'sort-vars': 0, // sort variables within the same declaration block (off by default) - 'space-in-brackets': 0, // require or disallow spaces inside brackets (off by default) - 'space-in-parens': 0, // require or disallow spaces inside parentheses (off by default) - 'space-infix-ops': 1, // require spaces around operators - 'space-unary-ops': [1, {words: true, nonwords: false}], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default) - 'max-nested-callbacks': 0, // specify the maximum depth callbacks can be nested (off by default) - 'one-var': 0, // allow just one var statement per function (off by default) - 'wrap-regex': 0, // require regex literals to be wrapped in parentheses (off by default) - - // Legacy - // The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same. - - 'max-depth': 0, // specify the maximum depth that blocks can be nested (off by default) - 'max-len': 0, // specify the maximum length of a line in your program (off by default) - 'max-params': 0, // limits the number of parameters that can be used in the function declaration. (off by default) - 'max-statements': 0, // specify the maximum number of statement allowed in a function (off by default) - 'no-bitwise': 1, // disallow use of bitwise operators (off by default) - 'no-plusplus': 0, // disallow use of unary operators, ++ and -- (off by default) - - // React Plugin - // The following rules are made available via `eslint-plugin-react`. - - 'react/display-name': 0, - 'react/jsx-boolean-value': 0, - 'react/jsx-no-comment-textnodes': 2, - 'react/jsx-no-duplicate-props': 2, - 'react/jsx-no-undef': 2, - 'react/jsx-sort-props': 0, - 'react/jsx-uses-react': 1, - 'react/jsx-uses-vars': 1, - 'react/no-did-mount-set-state': 1, - 'react/no-did-update-set-state': 1, - 'react/no-multi-comp': 0, - 'react/no-string-refs': 2, - 'react/no-unknown-property': 0, - 'react/no-unstable-nested-components': 1, - 'react/prop-types': 0, - 'react/react-in-jsx-scope': 1, - 'react/self-closing-comp': 1, - 'react/wrap-multilines': 0, - - // React-Hooks Plugin - // The following rules are made available via `eslint-plugin-react-hooks` - 'react-hooks/rules-of-hooks': 2, - 'react-hooks/exhaustive-deps': 2, - - // React-Native Plugin - // The following rules are made available via `eslint-plugin-react-native` - - 'react-native/no-inline-styles': 1, - - // Jest Plugin - // The following rules are made available via `eslint-plugin-jest`. - 'jest/no-disabled-tests': 1, - 'jest/no-focused-tests': 1, - 'jest/no-identical-title': 1, - 'jest/valid-expect': 1, -}; - -const plugin = { - configs: { - legacy: { - parserOptions: { - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - extends: ['plugin:prettier/recommended'], - - plugins: [ - 'eslint-comments', - 'react', - 'react-hooks', - 'react-native', - '@react-native', - 'jest', - ], - - settings: { - react: { - version: 'detect', - }, - }, - - overrides: [ - { - files: ['*.js'], - parser: '@babel/eslint-parser', - plugins: ['ft-flow'], - rules: { - // Flow Plugin - // The following rules are made available via `eslint-plugin-ft-flow` - - 'ft-flow/define-flow-type': 1, - 'ft-flow/use-flow-type': 1, - }, - }, - { - files: ['*.jsx'], - parser: '@babel/eslint-parser', - }, - { - files: ['*.ts', '*.tsx'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint/eslint-plugin'], - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - }, - ], - 'no-unused-vars': 'off', - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 1, - 'no-undef': 'off', - 'func-call-spacing': 'off', - '@typescript-eslint/func-call-spacing': 1, - }, - }, - { - files: [ - '*.{spec,test}.{js,ts,tsx}', - '**/__{mocks,tests}__/**/*.{js,ts,tsx}', - ], - env: { - jest: true, - 'jest/globals': true, - }, - rules: { - 'react-native/no-inline-styles': 0, - quotes: [ - 1, - 'single', - {avoidEscape: true, allowTemplateLiterals: true}, - ], - }, - }, - ], - globals: globals, - rules: rules, - }, - }, -}; - -plugin.configs.flat = [ - prettier, - { - files: ['*.js'], - languageOptions: { - parser: babelParser, - }, - plugins: { - 'ft-flow': ftFlow, - }, - rules: { - // Flow Plugin - // The following rules are made available via `eslint-plugin-ft-flow` - 'ft-flow/define-flow-type': 1, - 'ft-flow/use-flow-type': 1, - }, - }, - { - files: ['*.jsx'], - languageOptions: { - parser: babelParser, - }, - }, - { - files: ['*.ts', '*.tsx'], - languageOptions: { - parser: typescriptParser, - }, - plugins: { - '@typescript-eslint': typescriptPlugin, - }, - rules: { - '@typescript-eslint/no-shadow': 1, - '@typescript-eslint/func-call-spacing': 1, - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - }, - ], - 'no-unused-vars': 'off', - 'no-shadow': 'off', - 'no-undef': 'off', - 'func-call-spacing': 'off', - }, - }, - { - files: [ - '*.{spec,test}.{js,ts,tsx}', - '**/__{mocks,tests}__/**/*.{js,ts,tsx}', - ], - rules: { - 'react-native/no-inline-styles': 0, - quotes: [1, 'single', {avoidEscape: true, allowTemplateLiterals: true}], - }, - }, - { - plugins: { - 'eslint-comments': eslintComments, - react, - 'react-hooks': reactHooks, - 'react-native': reactNative, - '@react-native': reactNativeCommunity, - jest, - }, - languageOptions: { - sourceType: 'module', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - globals, - }, - settings: { - react: { - version: 'detect', - }, - }, - - rules, - }, -]; - -module.exports = plugin; diff --git a/packages/eslint-config-react-native/package.json b/packages/eslint-config-react-native/package.json deleted file mode 100644 index 08600343daf544..00000000000000 --- a/packages/eslint-config-react-native/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@react-native/eslint-config", - "version": "0.76.0-main", - "description": "ESLint config for React Native", - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/facebook/react-native.git", - "directory": "packages/eslint-config-react-native" - }, - "homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/eslint-config-react-native#readme", - "keywords": [ - "eslint", - "config", - "react-native" - ], - "bugs": "https://github.com/facebook/react-native/issues", - "engines": { - "node": ">=18" - }, - "main": "index.js", - "dependencies": { - "@babel/core": "^7.20.0", - "@babel/eslint-parser": "^7.20.0", - "@react-native/eslint-plugin": "0.76.0-main", - "@typescript-eslint/eslint-plugin": "^7.1.1", - "@typescript-eslint/parser": "^7.1.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-ft-flow": "^3.0.7", - "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-react": "^7.30.1", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-native": "^4.0.0" - }, - "peerDependencies": { - "eslint": ">=8", - "prettier": ">=2" - }, - "devDependencies": { - "eslint": "^8.57.0", - "prettier": "2.8.8" - } -} diff --git a/packages/eslint-plugin-react-native/README.md b/packages/eslint-plugin-react-native/README.md index 7871cfd016891c..84badf830b7d39 100644 --- a/packages/eslint-plugin-react-native/README.md +++ b/packages/eslint-plugin-react-native/README.md @@ -1,11 +1,14 @@ # @react-native/eslint-plugin -This plugin is intended to be used in [`@react-native/eslint-config`](https://github.com/facebook/react-native/tree/HEAD/packages/eslint-config-react-native). You probably want to install that package instead. +[![Version][version-badge]][package] + +## About +This plugin exports a recommended eslint config for React Native projects ## Installation ``` -yarn add --dev eslint @react-native/eslint-plugin +yarn add --dev eslint prettier @react-native/eslint-config ``` *Note: We're using `yarn` to install deps. Feel free to change commands to use `npm` 3+ and `npx` if you like* @@ -16,11 +19,13 @@ From [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0) onwards, ```javascript const reactNative = require('@react-native/eslint-plugin'); +const myplugin = require('my-plugin'); -module.exports = [ +module.exports = [ + ...reactNative.configs.flat, { plugins: { - reactNative + myplugin }, ... }, @@ -29,6 +34,42 @@ module.exports = [ If you're still using a version of eslint < `v8.23.0` or still using the old configuration files, place the following on your eslint config file (`.eslintrc`, or `eslintConfig` field in `package.json`): +```json +{ + "extends": "plugin:@react-native/legacy" +} +``` + +## Plugin supported Eslint versions + +| Eslint version | `.eslintrc` support | `eslint.config.js` support | +| :------------------- | :-----------------: | :------------------------: | +| `>= 9.0.0` | ❌ | ✅ | +| `>= 8.23.0 < 9.0.0` | ✅ | ✅ | +| `< 8.23.0` | ✅ | ❌ | + + +## Manual Configuration + +This plugin also exports rules that you can manually configure by importing this package as a plugin + +## Usage + +```javascript +const reactNative = require('@react-native/eslint-plugin'); + +module.exports = [ + { + plugins: { + reactNative + }, + ... + }, +]; +``` + +If you're still using a version of eslint < `v8.23.0` or still using the old configuration files (`.eslintrc`, or `eslintConfig` field in `package.json`): + ```json { "plugins": ["@react-native"] @@ -47,3 +88,8 @@ To run the tests in this package, run the following commands from the React Nati 1. `yarn` to install the dependencies. You just need to run this once 2. `yarn jest packages/eslint-plugin-react-native`. + + +[version-badge]: https://img.shields.io/npm/v/@react-native/eslint-plugin.svg?style=flat-square +[package]: https://www.npmjs.com/package/@react-native/eslint-plugin + diff --git a/packages/eslint-plugin-react-native/__tests__/platform-colors-test.js b/packages/eslint-plugin-react-native/__tests__/platform-colors-test.js index fceb13bb7acd9f..20bc8f7a8a9ae9 100644 --- a/packages/eslint-plugin-react-native/__tests__/platform-colors-test.js +++ b/packages/eslint-plugin-react-native/__tests__/platform-colors-test.js @@ -10,7 +10,7 @@ 'use strict'; -const rule = require('../platform-colors.js'); +const rule = require('../rules/platform-colors.js'); const ESLintTester = require('./eslint-tester.js'); const eslintTester = new ESLintTester(); diff --git a/packages/eslint-plugin-react-native/index.js b/packages/eslint-plugin-react-native/index.js index ddcb68a0705fd2..0d4519b700f380 100644 --- a/packages/eslint-plugin-react-native/index.js +++ b/packages/eslint-plugin-react-native/index.js @@ -6,6 +6,8 @@ * * @format */ +const allRules = require('./rules'); +const compat = require('@eslint/compat') const eslintComments = require('eslint-plugin-eslint-comments'); const react = require('eslint-plugin-react'); const reactHooks = require('eslint-plugin-react-hooks'); @@ -66,9 +68,6 @@ const globals = { }; const rules = { - // Local Rules - 'platform-colors': require('./platform-colors'), - // General 'comma-dangle': [1, 'always-multiline'], // allow or disallow trailing commas 'no-cond-assign': 1, // disallow assignment in conditional expressions @@ -268,6 +267,7 @@ const rules = { }; const plugin = { + rules: allRules, configs: { legacy: { parserOptions: { @@ -417,7 +417,7 @@ plugin.configs.flat = [ 'eslint-comments': eslintComments, react, 'react-hooks': reactHooks, - 'react-native': reactNative, + 'react-native': compat.fixupPluginRules(reactNative), '@react-native': reactNativeCommunity, jest, }, diff --git a/packages/eslint-plugin-react-native/package.json b/packages/eslint-plugin-react-native/package.json index 97a999e09359bf..2e1c6a74ed8466 100644 --- a/packages/eslint-plugin-react-native/package.json +++ b/packages/eslint-plugin-react-native/package.json @@ -23,12 +23,13 @@ "dependencies": { "@babel/core": "^7.20.0", "@babel/eslint-parser": "^7.20.0", + "@eslint/compat": "^1.1.1", "@react-native/eslint-plugin": "0.76.0-main", "@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/parser": "^7.1.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-ft-flow": "^3.0.7", + "eslint-plugin-ft-flow": "^3.0.10", "eslint-plugin-jest": "^27.9.0", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/packages/eslint-plugin-react-native/rules/index.js b/packages/eslint-plugin-react-native/rules/index.js new file mode 100644 index 00000000000000..3f9207fb8afc53 --- /dev/null +++ b/packages/eslint-plugin-react-native/rules/index.js @@ -0,0 +1,8 @@ +'use strict'; + +/* eslint global-require: 0 */ + +/** @satisfies {Record} */ +module.exports = { + 'platform-colors': require('./platform-colors'), +}; \ No newline at end of file diff --git a/packages/eslint-plugin-react-native/platform-colors.js b/packages/eslint-plugin-react-native/rules/platform-colors.js similarity index 100% rename from packages/eslint-plugin-react-native/platform-colors.js rename to packages/eslint-plugin-react-native/rules/platform-colors.js