diff --git a/.eslintrc.js b/.eslintrc.js index d8b08a420b..d814d652ba 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,24 +22,110 @@ module.exports = { 'sourceType': 'module' }, 'plugins': [ + 'simple-import-sort', 'react' ], 'ignorePatterns': ['**/static/**/*.js'], 'rules': { - 'indent': 'off', + // Disable unused rules 'no-empty-pattern': 'off', - 'linebreak-style': [ + + // Unix linebreaks only + 'linebreak-style': ['error', 'unix'], + + // Single quotes, allow double to avoid escaping + 'quotes': [ 'error', - 'unix' + 'single', + { 'avoidEscape': true } ], - 'quotes': [ + + // No semicolons + 'semi': ['error', 'never'], + + // Maximum line length of 120 characters + 'max-len': [ + 'error', + { + 'code': 120, + 'ignoreUrls': true, + 'ignoreRegExpLiterals': true + } + ], + + // Indent by 2 spaces + 'indent': ['error', 2, { + 'SwitchCase': 1, + }], + + // Import order + 'simple-import-sort/imports': ['error', { + groups: [ + // external imports in the given order + ['^react$', '^prop-types$', '^react', '^[a-z]', '^lodash'], + // rdmo imports: lowercase first, then capitalized components + ['^rdmo/.*\\/[a-z]'], + ['^rdmo/.*\\/[A-Z]'], + // parent imports: lowercase first, then capitalized components + ['^\\.\\..*\\/[a-z]'], + ['^\\.\\..*\\/[A-Z]'], + // sibling imports: lowercase first, then capitalized components + ['^\\./.*\\/[a-z]'], + ['^\\./.*\\/[A-Z]'], + ], + }], + + // Export order + 'simple-import-sort/exports': 'error', + + // Disallow newlines between the operands of a ternary expression + 'multiline-ternary': ['error', 'never'], + + // Ensure spaces after commas + 'comma-spacing': ['error', { before: false, after: true }], + + // Ensure correct multiline imports + 'object-curly-newline': ['error', { + ImportDeclaration: { + multiline: true, + consistent: true + } + }], + + // JSX: wrap multiline expressions in parens, opening paren on a new line + 'react/jsx-wrap-multilines': [ 'error', - 'single' + { + 'declaration': 'parens-new-line', + 'assignment': 'parens-new-line', + 'return': 'parens-new-line', + 'arrow': 'parens-new-line', + 'condition': 'parens-new-line', + 'logical': 'parens-new-line', + 'prop': 'parens-new-line' + } ], - 'semi': [ + + // JSX curly braces: require newlines inside for multiline expressions + 'react/jsx-curly-newline': [ 'error', - 'never' - ] + { + 'multiline': 'require', + 'singleline': 'consistent' + } + ], + + // JSX curly brace spacing: no spaces inside { } + 'react/jsx-curly-spacing': [ + 'error', + { + 'when': 'never', + 'children': true + } + ], + + // JSX double quotes for props + 'jsx-quotes': ['error', 'prefer-double'], }, 'settings': { 'react': { diff --git a/package-lock.json b/package-lock.json index 3ac12ecedd..743d7e9310 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,6 +46,7 @@ "css-loader": "^7.1.1", "eslint": "~8.56.0", "eslint-plugin-react": "^7.37.2", + "eslint-plugin-simple-import-sort": "^12.1.1", "file-loader": "^6.2.0", "mini-css-extract-plugin": "^2.9.0", "sass": "^1.94.2", @@ -4406,6 +4407,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -11440,6 +11451,13 @@ } } }, + "eslint-plugin-simple-import-sort": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", + "dev": true, + "requires": {} + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", diff --git a/package.json b/package.json index b9411d6c06..b2f660596f 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "css-loader": "^7.1.1", "eslint": "~8.56.0", "eslint-plugin-react": "^7.37.2", + "eslint-plugin-simple-import-sort": "^12.1.1", "file-loader": "^6.2.0", "mini-css-extract-plugin": "^2.9.0", "sass": "^1.94.2",