diff --git a/.changeset/gorgeous-llamas-sparkle.md b/.changeset/gorgeous-llamas-sparkle.md new file mode 100644 index 0000000..2d6b21f --- /dev/null +++ b/.changeset/gorgeous-llamas-sparkle.md @@ -0,0 +1,6 @@ +--- +'@chotot/eslint-config-base': minor +'@chotot/eslint-config-next': minor +--- + +change structures, chotot-next depends on chotot-base diff --git a/packages/eslint-config-bare/CHANGELOG.md b/packages/eslint-config-base/CHANGELOG.md similarity index 100% rename from packages/eslint-config-bare/CHANGELOG.md rename to packages/eslint-config-base/CHANGELOG.md diff --git a/packages/eslint-config-bare/package.json b/packages/eslint-config-base/package.json similarity index 50% rename from packages/eslint-config-bare/package.json rename to packages/eslint-config-base/package.json index 8e2179e..595cd99 100644 --- a/packages/eslint-config-bare/package.json +++ b/packages/eslint-config-base/package.json @@ -1,16 +1,16 @@ { - "name": "@chotot/eslint-config-bare", + "name": "@chotot/eslint-config-base", "version": "1.3.1", "description": "Chotot's ESLint config for Typescript/Javascript application", - "main": "index.js", + "main": "src/index.js", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/ChoTotOSS/chotot-web-standards", - "directory": "packages/eslint-config-bare" + "directory": "packages/eslint-config-base" }, "files": [ - "index.js" + "src" ], "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0", @@ -22,12 +22,11 @@ } }, "dependencies": { - "@rushstack/eslint-patch": "1.3.2", - "@typescript-eslint/eslint-plugin": "5.62.0", - "@typescript-eslint/parser": "5.62.0", - "eslint-import-resolver-node": "0.3.7", - "eslint-import-resolver-typescript": "3.5.5", - "eslint-plugin-import": "2.27.5", - "@chotot/eslint-ruleset": "workspace:*" + "@rushstack/eslint-patch": "^1.3.2", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-import": "^2.27.5" } } diff --git a/packages/eslint-config-bare/index.js b/packages/eslint-config-base/src/index.js similarity index 97% rename from packages/eslint-config-bare/index.js rename to packages/eslint-config-base/src/index.js index c93deda..1fdd78a 100644 --- a/packages/eslint-config-bare/index.js +++ b/packages/eslint-config-base/src/index.js @@ -6,7 +6,7 @@ const { eslintBuiltInRules, importPluginRules, typescriptEslintPluginRules, -} = require('@chotot/eslint-ruleset'); +} = require('./rulesets'); module.exports = { root: true, diff --git a/packages/eslint-ruleset/src/index.js b/packages/eslint-config-base/src/rulesets.js similarity index 62% rename from packages/eslint-ruleset/src/index.js rename to packages/eslint-config-base/src/rulesets.js index 055bac7..c22ec03 100644 --- a/packages/eslint-ruleset/src/index.js +++ b/packages/eslint-config-base/src/rulesets.js @@ -787,629 +787,6 @@ const importPluginRules = { 'import/default': 'error', }; -const reactJSXA11yPluginRules = { - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/alt-text.md - 'jsx-a11y/alt-text': 'error', - // Enforces values are not exact matches for the phrases "click here", "here", "link", "a link", or "learn more". - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-ambiguous-text.md - 'jsx-a11y/anchor-ambiguous-text': 'off', - // Enforce that anchors have content and that the content is accessible to screen readers. - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-has-content.md - 'jsx-a11y/anchor-has-content': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-is-valid.md - 'jsx-a11y/anchor-is-valid': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-activedescendant-has-tabindex.md - 'jsx-a11y/aria-activedescendant-has-tabindex': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-props.md - 'jsx-a11y/aria-props': 'warn', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-proptypes.md - 'jsx-a11y/aria-proptypes': 'warn', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-role.md - 'jsx-a11y/aria-role': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-unsupported-elements.md - 'jsx-a11y/aria-unsupported-elements': 'warn', - // Ensure the autocomplete attribute is correct and suitable for the form field it is used with. - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/autocomplete-valid.md - 'jsx-a11y/autocomplete-valid': 'error', - // Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress. - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/click-events-have-key-events.md - 'jsx-a11y/click-events-have-key-events': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/control-has-associated-label.md - 'jsx-a11y/control-has-associated-label': [ - 'error', - { - ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'], - ignoreRoles: [ - 'grid', - 'listbox', - 'menu', - 'menubar', - 'radiogroup', - 'row', - 'tablist', - 'toolbar', - 'tree', - 'treegrid', - ], - includeRoles: ['alert', 'dialog'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/heading-has-content.md - 'jsx-a11y/heading-has-content': 'error', - // elements must have the lang prop. - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/html-has-lang.md - 'jsx-a11y/html-has-lang': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/iframe-has-title.md - 'jsx-a11y/iframe-has-title': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/img-redundant-alt.md - 'jsx-a11y/img-redundant-alt': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/interactive-supports-focus.md - 'jsx-a11y/interactive-supports-focus': [ - 'error', - { - tabbable: ['button', 'checkbox', 'link', 'searchbox', 'spinbutton', 'switch', 'textbox'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md - 'jsx-a11y/label-has-associated-control': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-for.md - 'jsx-a11y/label-has-for': 'off', - // The lang prop on the element must be a valid IETF's BCP 47 language tag. - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/lang.md - 'jsx-a11y/lang': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/media-has-caption.md - 'jsx-a11y/media-has-caption': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/mouse-events-have-key-events.md - 'jsx-a11y/mouse-events-have-key-events': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-access-key.md - 'jsx-a11y/no-access-key': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-autofocus.md - 'jsx-a11y/no-autofocus': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-distracting-elements.md - 'jsx-a11y/no-distracting-elements': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-interactive-element-to-noninteractive-role.md - 'jsx-a11y/no-interactive-element-to-noninteractive-role': [ - 'error', - { - tr: ['none', 'presentation'], - canvas: ['img'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-element-interactions.md - 'jsx-a11y/no-noninteractive-element-interactions': [ - 'error', - { - handlers: [ - 'onClick', - 'onError', - 'onLoad', - 'onMouseDown', - 'onMouseUp', - 'onKeyPress', - 'onKeyDown', - 'onKeyUp', - ], - alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'], - body: ['onError', 'onLoad'], - dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'], - iframe: ['onError', 'onLoad'], - img: ['onError', 'onLoad'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-element-to-interactive-role.md - 'jsx-a11y/no-noninteractive-element-to-interactive-role': [ - 'error', - { - ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], - ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], - li: ['menuitem', 'option', 'row', 'tab', 'treeitem'], - table: ['grid'], - td: ['gridcell'], - fieldset: ['radiogroup', 'presentation'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-tabindex.md - 'jsx-a11y/no-noninteractive-tabindex': [ - 'error', - { - tags: [], - roles: ['tabpanel'], - allowExpressionValues: true, - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-redundant-roles.md - 'jsx-a11y/no-redundant-roles': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-static-element-interactions.md - 'jsx-a11y/no-static-element-interactions': [ - 'error', - { - allowExpressionValues: true, - handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'], - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/role-has-required-aria-props.md - 'jsx-a11y/role-has-required-aria-props': 'warn', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/role-supports-aria-props.md - 'jsx-a11y/role-supports-aria-props': 'warn', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/scope.md - 'jsx-a11y/scope': 'error', - // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/tabindex-no-positive.md - 'jsx-a11y/tabindex-no-positive': 'error', -}; - -const reactPluginRules = { - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md - 'react/jsx-sort-props': [ - 'off', - { - callbacksLast: true, - shorthandFirst: true, - noSortAlphabetically: false, - reservedFirst: true, - locale: 'auto', - }, - ], - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md - 'react/function-component-definition': [ - 'error', - { - namedComponents: 'arrow-function', - }, - ], - // Allows you to enforce a consistent naming pattern for props which expect a boolean value. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/boolean-prop-naming.md - 'react/boolean-prop-naming': [ - 'off', - { - propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'], - rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+', - message: '', - }, - ], - // Prevent usage of button elements without an explicit type attribute - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/button-has-type.md - 'react/button-has-type': [ - 'error', - { - button: true, - submit: true, - reset: false, - }, - ], - // Enforce all defaultProps have a corresponding non-required PropType - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/default-props-match-prop-types.md - 'react/default-props-match-prop-types': ['off', { allowRequiredDefaults: false }], - // Enforce consistent usage of destructuring assignment of props, state, and context - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/destructuring-assignment.md - // OFF - 'react/destructuring-assignment': ['off', 'always'], - // DisplayName allows you to name your component. This name is used by React in debugging messages. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md - // OFF - 'react/display-name': ['off', { ignoreTranspilerName: false }], - // Forbid certain props on Components - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-component-props.md - // OFF - 'react/forbid-component-props': ['off', { forbid: [] }], - // Forbid certain props on DOM Nodes - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-dom-props.md - // OFF - 'react/forbid-dom-props': ['off', { forbid: [] }], - // Forbid certain elements - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-elements.md - // OFF - 'react/forbid-elements': ['off', { forbid: [] }], - // Forbids using non-exported propTypes - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md - // OFF - 'react/forbid-foreign-prop-types': ['warn', { allowInPropTypes: true }], - // Forbid certain propTypes (any, array, object) - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md - 'react/forbid-prop-types': [ - 'error', - { - forbid: ['any', 'array', 'object'], - checkContextTypes: true, - checkChildContextTypes: true, - }, - ], - // This rule checks whether the value and setter variables destructured from a React.useState() call are named symmetrically. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/hook-use-state.md - 'react/hook-use-state': 'off', - // Enforce sandbox attribute on iframe elements - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/iframe-missing-sandbox.md - 'react/iframe-missing-sandbox': 'error', - // Enforce boolean attributes notation in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md - 'react/jsx-boolean-value': ['error', 'never', { always: [] }], - // Ensures inline tags are not rendered without spaces between them - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-child-element-spacing.md - 'react/jsx-child-element-spacing': 'off', - // Validate closing bracket location in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md - 'react/jsx-closing-bracket-location': ['error', 'line-aligned'], - // Validate closing tag location in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md - // DISABLE: sometimes conflict with prettier - 'react/jsx-closing-tag-location': 'off', - // Enforce curly braces or disallow unnecessary curly braces in JSX props and/or children - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md - 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }], - // DISABLE for prettier: Enforce linebreaks in curly braces in JSX attributes and expressions. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-newline.md - 'react/jsx-curly-newline': [ - 'off', - { - multiline: 'consistent', - singleline: 'consistent', - }, - ], - // Enforce or disallow spaces inside of curly braces in JSX attributes - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md - 'react/jsx-curly-spacing': ['error', 'never', { allowMultiline: true }], - // Enforce spacing around jsx equals signs - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-equals-spacing.md - 'react/jsx-equals-spacing': ['error', 'never'], - // DISABLE: only .jsx files may have JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md - 'react/jsx-filename-extension': 'off', - // Require that the first prop in a JSX element be on a new line when the element is multiline - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md - 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'], - // DISABLE: Enforce shorthand or standard form for React fragments - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-fragments.md - 'react/jsx-fragments': ['off', 'syntax'], - // Enforce event handler naming conventions in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md - 'react/jsx-handler-names': [ - 'off', - { - eventHandlerPrefix: 'handle', - eventHandlerPropPrefix: 'on', - }, - ], - // Validate props indentation in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md - 'react/jsx-indent-props': ['error', 2], - // DISABLE for prettier: Enforce JSX indentation - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md - 'react/jsx-indent': ['off', 2], - // Validate JSX has key prop when in array or iterator - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-key.md - 'react/jsx-key': 'error', - // Validate JSX maximum depth - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-depth.md - 'react/jsx-max-depth': 'off', - // Limit maximum of props on a single line in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md - 'react/jsx-max-props-per-line': ['off', { maximum: 1, when: 'multiline' }], - // DISABLED: This is a stylistic rule intended to make JSX code more readable by requiring or preventing lines between adjacent JSX elements and expressions. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-newline.md - 'react/jsx-newline': 'off', - // Prevent usage of .bind() in JSX props - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md - 'react/jsx-no-bind': [ - 'error', - { - ignoreRefs: true, - allowArrowFunctions: true, - allowFunctions: false, - allowBind: false, - ignoreDOMComponents: true, - }, - ], - // prevent accidental JS comments from being injected into JSX as text - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md - 'react/jsx-no-comment-textnodes': 'error', - // This rule prevents non-stable values (i.e. object identities) from being used as a value for Context.Provider. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-constructed-context-values.md - 'react/jsx-no-constructed-context-values': 'error', - // Prevent duplicate props in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md - 'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }], - // Disallow problematic leaked values from being rendered - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-leaked-render.md - 'react/jsx-no-leaked-render': 'error', - // Prevent usage of unwrapped JSX strings - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md - 'react/jsx-no-literals': ['off', { noStrings: true }], - // Disallow target="_blank" on links - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md - 'react/jsx-no-target-blank': ['error', { enforceDynamicLinks: 'always' }], - // Disallow undeclared variables in JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md - 'react/jsx-no-undef': 'error', - // Disallow unnecessary fragments - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md - 'react/jsx-no-useless-fragment': 'error', - // DISABLE for prettier: One JSX Element Per Line - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-one-expression-per-line.md - 'react/jsx-one-expression-per-line': ['off', { allow: 'single-child' }], - // Enforce PascalCase for user-defined JSX components - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md - 'react/jsx-pascal-case': [ - 'error', - { - allowAllCaps: true, - ignore: [], - }, - ], - // Disallow multiple spaces between inline JSX props - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-multi-spaces.md - 'react/jsx-props-no-multi-spaces': 'error', - // Disallow JSX props spreading - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md - 'react/jsx-props-no-spreading': 'off', - // Deprecated in favor of react/jsx-sort-props - 'react/jsx-sort-prop-types': 'off', - // Validate whitespace in and around the JSX opening and closing brackets - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md - 'react/jsx-tag-spacing': [ - 'error', - { - closingSlash: 'never', - beforeSelfClosing: 'always', - afterOpening: 'never', - beforeClosing: 'never', - }, - ], - // Prevent React to be incorrectly marked as unused - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md - 'react/jsx-uses-react': ['error'], - // Prevent variables used in JSX to be incorrectly marked as unused - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md - 'react/jsx-uses-vars': 'error', - // Prevent missing parentheses around multilines JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md - // DISABLE: conflict with prettier - 'react/jsx-wrap-multilines': [ - 'off', - { - 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: 'ignore', - }, - ], - // Prevent using this.state within a this.setState - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-access-state-in-setstate.md - 'react/no-access-state-in-setstate': 'error', - // Prevent adjacent inline elements not separated by whitespace. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md - 'react/no-adjacent-inline-elements': 'off', - // Prevent usage of Array index in keys - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md - 'react/no-array-index-key': 'error', - // Lifecycle methods should be methods on the prototype, not class fields - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-arrow-function-lifecycle.md - 'react/no-arrow-function-lifecycle': 'off', - // Prevent passing of children as props - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md - 'react/no-children-prop': 'error', - // Prevent problem with children and props.dangerouslySetInnerHTML - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md - 'react/no-danger-with-children': 'error', - // Prevent usage of dangerous JSX properties - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger.md - 'react/no-danger': 'warn', - // Prevent usage of deprecated methods - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md - 'react/no-deprecated': ['error'], - // Prevent usage of setState in componentDidMount - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md - // this is necessary for server-rendering - 'react/no-did-mount-set-state': 'off', - // Prevent usage of setState in componentDidUpdate - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md - 'react/no-did-update-set-state': 'error', - // Prevent direct mutation of this.state - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md - 'react/no-direct-mutation-state': 'error', - // warn against using findDOMNode() - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md - 'react/no-find-dom-node': 'error', - // Prevent usage of invalid attributes - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-invalid-html-attribute.md - 'react/no-invalid-html-attribute': 'error', - // Prevent usage of isMounted - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md - 'react/no-is-mounted': 'error', - // Prevent multiple component definition per file - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md - 'react/no-multi-comp': 'off', - // Enforce that namespaces are not used in React elements - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-namespace.md - 'react/no-namespace': 'error', - // Prevent usage of shouldComponentUpdate when extending React.PureComponent - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-redundant-should-component-update.md - 'react/no-redundant-should-component-update': 'error', - // disallow using React.render/ReactDOM.render's return value - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md - 'react/no-render-return-value': 'error', - // Prevent usage of setState - // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-set-state.md - 'react/no-set-state': 'off', - // DISABLE: Prevent using string references - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md - 'react/no-string-refs': 'off', - // Prevent this from being used in stateless functional components - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-this-in-sfc.md - 'react/no-this-in-sfc': 'error', - // Prevents common casing typos - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-typos.md - 'react/no-typos': 'error', - // Prevent invalid characters from appearing in markup - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md - 'react/no-unescaped-entities': 'error', - // Prevent usage of unknown DOM property - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md - 'react/no-unknown-property': 'error', - // Prevent usage of UNSAFE_ methods - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unsafe.md - 'react/no-unsafe': 'off', - // Creating components inside components without memoization leads to unstable components. The nested component and all - // its children are recreated during each re-render. Given stateful children of the nested component will lose their state on each re-render. - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unstable-nested-components.md - 'react/no-unstable-nested-components': ['error', { allowAsProps: false }], - // Prevent declaring unused methods of component class - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-class-component-methods.md - 'react/no-unused-class-component-methods': 'error', - // Prevent unused propType definitions - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-prop-types.md - 'react/no-unused-prop-types': [ - 'error', - { - customValidators: [], - skipShapeProps: true, - }, - ], - // Prevent unused state values - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-state.md - 'react/no-unused-state': 'error', - // Prevent usage of setState in componentWillUpdate - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-will-update-set-state.md - 'react/no-will-update-set-state': 'error', - // Require ES6 class declarations over React.createClass - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md - 'react/prefer-es6-class': ['error', 'always'], - // Prefer exact proptype definitions - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-exact-props.md - 'react/prefer-exact-props': 'warn', - // Enforce that props are read-only - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-read-only-props.md - 'react/prefer-read-only-props': 'off', - // DISABLE: Require stateless functions when not using lifecycle methods, setState or ref - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md - 'react/prefer-stateless-function': 'off', - // Prevent missing props validation in a React component definition - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prop-types.md - // OFF: use typescript - 'react/prop-types': [ - 'off', - { - ignore: [], - customValidators: [], - skipUndeclared: false, - }, - ], - // Prevent missing React when using JSX - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md - 'react/react-in-jsx-scope': 'off', - // Enforce a defaultProps definition for every prop that is not a required prop - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-default-props.md - 'react/require-default-props': 'off', - // require a shouldComponentUpdate method, or PureRenderMixin - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-optimization.md - 'react/require-optimization': ['off', { allowDecorators: [] }], - // Require render() methods to return something - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md - 'react/require-render-return': 'error', - // Prevent extra closing tags for components without children - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md - 'react/self-closing-comp': 'error', - // Enforce propTypes declarations alphabetical sorting - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md - 'react/sort-prop-types': [ - 'off', - { - ignoreCase: true, - callbacksLast: false, - requiredFirst: false, - sortShapeProp: true, - }, - ], - // Enforce state initialization style - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/state-in-constructor.md - 'react/state-in-constructor': ['error', 'never'], - // Enforces where React component static properties should be positioned - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/static-property-placement.md - 'react/static-property-placement': ['error', 'static public field'], - // Require style prop value be an object or var - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md - 'react/style-prop-object': 'error', - // Prevent void DOM elements from receiving children - // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md - 'react/void-dom-elements-no-children': 'error', -}; - -const reactHooksPluginRules = { - // https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js - 'react-hooks/rules-of-hooks': 'error', - // https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js - 'react-hooks/exhaustive-deps': 'warn', -}; - -const nextPluginRules = { - // Enforce font-display behavior with Google Fonts. - // https://nextjs.org/docs/messages/google-font-display - '@next/next/google-font-display': 'warn', - // Ensure preconnect is used with Google Fonts. - // https://nextjs.org/docs/messages/google-font-preconnect - '@next/next/google-font-preconnect': 'warn', - // Prefer next/script component when using the inline script for Google Analytics. - // https://nextjs.org/docs/messages/next-script-for-ga - '@next/next/next-script-for-ga': 'warn', - // Prevent usage of next/script's beforeInteractive strategy outside of pages/_document.js. - // https://nextjs.org/docs/messages/no-before-interactive-script-outside-document - '@next/next/no-before-interactive-script-outside-document': 'warn', - // Prevent manual stylesheet tags. - // https://nextjs.org/docs/messages/no-css-tags - '@next/next/no-css-tags': 'warn', - // Prevent usage of element. - // https://nextjs.org/docs/messages/no-head-element - '@next/next/no-head-element': 'warn', - // Prevent usage of elements to navigate to internal Next.js pages. - // https://nextjs.org/docs/messages/no-html-link-for-pages - '@next/next/no-html-link-for-pages': 'warn', - // Prevent usage of elements to navigate to internal Next.js pages. - // https://nextjs.org/docs/messages/no-html-link-for-pages - '@next/next/no-page-custom-font': 'warn', - // https://nextjs.org/docs/messages/no-styled-jsx-in-document - // Prevent usage of styled-jsx in pages/_document.js. - '@next/next/no-styled-jsx-in-document': 'warn', - // Prevent synchronous scripts. - // https://nextjs.org/docs/messages/no-sync-scripts - '@next/next/no-sync-scripts': 'warn', - // Prevent usage of with Head component from next/document. - // https://nextjs.org/docs/messages/no-title-in-document-head - '@next/next/no-title-in-document-head': 'warn', - // Prevent common typos in Next.js's data fetching functions - '@next/next/no-typos': 'warn', - // Prevent duplicate polyfills from Polyfill.io. - // https://nextjs.org/docs/messages/no-unwanted-polyfillio - '@next/next/no-unwanted-polyfillio': 'warn', - // https://nextjs.org/docs/messages/no-img-element - // Prevent usage of <img> element due to slower LCP and higher bandwidth. - '@next/next/no-img-element': 'off', - // Enforce id attribute on next/script components with inline content. - // https://nextjs.org/docs/messages/inline-script-id - '@next/next/inline-script-id': 'error', - // Prevent assignment to the module variable. - // https://nextjs.org/docs/messages/no-assign-module-variable - '@next/next/no-assign-module-variable': 'error', - // Prevent importing next/document outside of pages/_document.js. - // https://nextjs.org/docs/messages/no-document-import-in-page - '@next/next/no-document-import-in-page': 'error', - // Prevent duplicate usage of <Head> in pages/_document.js. - // https://nextjs.org/docs/messages/no-duplicate-head - '@next/next/no-duplicate-head': 'error', - // Prevent usage of next/head in pages/_document.js. - // https://nextjs.org/docs/messages/no-head-import-in-document - '@next/next/no-head-import-in-document': 'error', - // Prevent usage of next/script in next/head component. - // https://nextjs.org/docs/messages/no-script-component-in-head - '@next/next/no-script-component-in-head': 'error', - // Prevent usage of <a> elements to navigate to internal Next.js pages. - // https://nextjs.org/docs/messages/no-html-link-for-pages - '@next/next/no-html-link-for-pages': 'error', - // Prevent synchronous scripts. - // https://nextjs.org/docs/messages/no-sync-scripts - '@next/next/no-sync-scripts': 'error', -}; - const typescriptEslintPluginRules = { // disables rules from eslint:recommended which are already handled by TypeScript. // enables rules that make sense due to TS's typechecking / transpilation. @@ -1766,14 +1143,3 @@ const typescriptEslintPluginRules = { // https://typescript-eslint.io/rules/no-empty-function '@typescript-eslint/no-empty-function': 'off', }; - -module.exports = { - chototPluginRules, - eslintBuiltInRules, - importPluginRules, - reactJSXA11yPluginRules, - reactPluginRules, - reactHooksPluginRules, - nextPluginRules, - typescriptEslintPluginRules, -}; diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 39d80dc..b751193 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -2,7 +2,7 @@ "name": "@chotot/eslint-config-next", "version": "1.4.1", "description": "Chotot's ESLint config for Next.js application", - "main": "index.js", + "main": "src/index.js", "license": "MIT", "repository": { "type": "git", @@ -10,10 +10,11 @@ "directory": "packages/eslint-config-next" }, "files": [ - "index.js" + "src" ], "dependencies": { "@chotot/eslint-plugin-chotot": "workspace:*", + "@chotot/eslint-config-base": "workspace:*", "@typescript-eslint/eslint-plugin": "5.62.0", "eslint-config-next": "13.4.8", "@chotot/eslint-ruleset": "workspace:*" diff --git a/packages/eslint-config-next/index.js b/packages/eslint-config-next/src/index.js similarity index 82% rename from packages/eslint-config-next/index.js rename to packages/eslint-config-next/src/index.js index 8fa9f7f..5d08721 100644 --- a/packages/eslint-config-next/index.js +++ b/packages/eslint-config-next/src/index.js @@ -2,12 +2,15 @@ const { chototPluginRules, eslintBuiltInRules, importPluginRules, + typescriptEslintPluginRules, +} = require('@chotot/eslint-config-base'); + +const { reactJSXA11yPluginRules, reactPluginRules, reactHooksPluginRules, nextPluginRules, - typescriptEslintPluginRules -} = require('@chotot/eslint-ruleset'); +} = require('./rulesets'); /* eslint-env node */ module.exports = { @@ -28,7 +31,7 @@ module.exports = { ...reactJSXA11yPluginRules, ...reactPluginRules, ...reactHooksPluginRules, - ...nextPluginRules + ...nextPluginRules, }, overrides: [ { @@ -37,7 +40,7 @@ module.exports = { project: ['./tsconfig.json'], // Specify it only for TypeScript files }, rules: { - ...typescriptEslintPluginRules + ...typescriptEslintPluginRules, }, }, ], diff --git a/packages/eslint-config-next/src/rulesets.js b/packages/eslint-config-next/src/rulesets.js new file mode 100644 index 0000000..708d33b --- /dev/null +++ b/packages/eslint-config-next/src/rulesets.js @@ -0,0 +1,629 @@ +const reactJSXA11yPluginRules = { + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/alt-text.md + 'jsx-a11y/alt-text': 'error', + // Enforces <a> values are not exact matches for the phrases "click here", "here", "link", "a link", or "learn more". + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-ambiguous-text.md + 'jsx-a11y/anchor-ambiguous-text': 'off', + // Enforce that anchors have content and that the content is accessible to screen readers. + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-has-content.md + 'jsx-a11y/anchor-has-content': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/anchor-is-valid.md + 'jsx-a11y/anchor-is-valid': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-activedescendant-has-tabindex.md + 'jsx-a11y/aria-activedescendant-has-tabindex': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-props.md + 'jsx-a11y/aria-props': 'warn', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-proptypes.md + 'jsx-a11y/aria-proptypes': 'warn', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-role.md + 'jsx-a11y/aria-role': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/aria-unsupported-elements.md + 'jsx-a11y/aria-unsupported-elements': 'warn', + // Ensure the autocomplete attribute is correct and suitable for the form field it is used with. + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/autocomplete-valid.md + 'jsx-a11y/autocomplete-valid': 'error', + // Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress. + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/click-events-have-key-events.md + 'jsx-a11y/click-events-have-key-events': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/control-has-associated-label.md + 'jsx-a11y/control-has-associated-label': [ + 'error', + { + ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'], + ignoreRoles: [ + 'grid', + 'listbox', + 'menu', + 'menubar', + 'radiogroup', + 'row', + 'tablist', + 'toolbar', + 'tree', + 'treegrid', + ], + includeRoles: ['alert', 'dialog'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/heading-has-content.md + 'jsx-a11y/heading-has-content': 'error', + // elements must have the lang prop. + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/html-has-lang.md + 'jsx-a11y/html-has-lang': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/iframe-has-title.md + 'jsx-a11y/iframe-has-title': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/img-redundant-alt.md + 'jsx-a11y/img-redundant-alt': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/interactive-supports-focus.md + 'jsx-a11y/interactive-supports-focus': [ + 'error', + { + tabbable: ['button', 'checkbox', 'link', 'searchbox', 'spinbutton', 'switch', 'textbox'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md + 'jsx-a11y/label-has-associated-control': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-for.md + 'jsx-a11y/label-has-for': 'off', + // The lang prop on the <html> element must be a valid IETF's BCP 47 language tag. + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/lang.md + 'jsx-a11y/lang': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/media-has-caption.md + 'jsx-a11y/media-has-caption': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/mouse-events-have-key-events.md + 'jsx-a11y/mouse-events-have-key-events': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-access-key.md + 'jsx-a11y/no-access-key': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-autofocus.md + 'jsx-a11y/no-autofocus': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-distracting-elements.md + 'jsx-a11y/no-distracting-elements': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-interactive-element-to-noninteractive-role.md + 'jsx-a11y/no-interactive-element-to-noninteractive-role': [ + 'error', + { + tr: ['none', 'presentation'], + canvas: ['img'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-element-interactions.md + 'jsx-a11y/no-noninteractive-element-interactions': [ + 'error', + { + handlers: [ + 'onClick', + 'onError', + 'onLoad', + 'onMouseDown', + 'onMouseUp', + 'onKeyPress', + 'onKeyDown', + 'onKeyUp', + ], + alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'], + body: ['onError', 'onLoad'], + dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'], + iframe: ['onError', 'onLoad'], + img: ['onError', 'onLoad'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-element-to-interactive-role.md + 'jsx-a11y/no-noninteractive-element-to-interactive-role': [ + 'error', + { + ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], + ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'], + li: ['menuitem', 'option', 'row', 'tab', 'treeitem'], + table: ['grid'], + td: ['gridcell'], + fieldset: ['radiogroup', 'presentation'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-noninteractive-tabindex.md + 'jsx-a11y/no-noninteractive-tabindex': [ + 'error', + { + tags: [], + roles: ['tabpanel'], + allowExpressionValues: true, + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-redundant-roles.md + 'jsx-a11y/no-redundant-roles': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-static-element-interactions.md + 'jsx-a11y/no-static-element-interactions': [ + 'error', + { + allowExpressionValues: true, + handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'], + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/role-has-required-aria-props.md + 'jsx-a11y/role-has-required-aria-props': 'warn', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/role-supports-aria-props.md + 'jsx-a11y/role-supports-aria-props': 'warn', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/scope.md + 'jsx-a11y/scope': 'error', + // https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/tabindex-no-positive.md + 'jsx-a11y/tabindex-no-positive': 'error', +}; + +const reactPluginRules = { + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md + 'react/jsx-sort-props': [ + 'off', + { + callbacksLast: true, + shorthandFirst: true, + noSortAlphabetically: false, + reservedFirst: true, + locale: 'auto', + }, + ], + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md + 'react/function-component-definition': [ + 'error', + { + namedComponents: 'arrow-function', + }, + ], + // Allows you to enforce a consistent naming pattern for props which expect a boolean value. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/boolean-prop-naming.md + 'react/boolean-prop-naming': [ + 'off', + { + propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'], + rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+', + message: '', + }, + ], + // Prevent usage of button elements without an explicit type attribute + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/button-has-type.md + 'react/button-has-type': [ + 'error', + { + button: true, + submit: true, + reset: false, + }, + ], + // Enforce all defaultProps have a corresponding non-required PropType + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/default-props-match-prop-types.md + 'react/default-props-match-prop-types': ['off', { allowRequiredDefaults: false }], + // Enforce consistent usage of destructuring assignment of props, state, and context + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/destructuring-assignment.md + // OFF + 'react/destructuring-assignment': ['off', 'always'], + // DisplayName allows you to name your component. This name is used by React in debugging messages. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md + // OFF + 'react/display-name': ['off', { ignoreTranspilerName: false }], + // Forbid certain props on Components + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-component-props.md + // OFF + 'react/forbid-component-props': ['off', { forbid: [] }], + // Forbid certain props on DOM Nodes + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-dom-props.md + // OFF + 'react/forbid-dom-props': ['off', { forbid: [] }], + // Forbid certain elements + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-elements.md + // OFF + 'react/forbid-elements': ['off', { forbid: [] }], + // Forbids using non-exported propTypes + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md + // OFF + 'react/forbid-foreign-prop-types': ['warn', { allowInPropTypes: true }], + // Forbid certain propTypes (any, array, object) + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md + 'react/forbid-prop-types': [ + 'error', + { + forbid: ['any', 'array', 'object'], + checkContextTypes: true, + checkChildContextTypes: true, + }, + ], + // This rule checks whether the value and setter variables destructured from a React.useState() call are named symmetrically. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/hook-use-state.md + 'react/hook-use-state': 'off', + // Enforce sandbox attribute on iframe elements + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/iframe-missing-sandbox.md + 'react/iframe-missing-sandbox': 'error', + // Enforce boolean attributes notation in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md + 'react/jsx-boolean-value': ['error', 'never', { always: [] }], + // Ensures inline tags are not rendered without spaces between them + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-child-element-spacing.md + 'react/jsx-child-element-spacing': 'off', + // Validate closing bracket location in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md + 'react/jsx-closing-bracket-location': ['error', 'line-aligned'], + // Validate closing tag location in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md + // DISABLE: sometimes conflict with prettier + 'react/jsx-closing-tag-location': 'off', + // Enforce curly braces or disallow unnecessary curly braces in JSX props and/or children + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md + 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }], + // DISABLE for prettier: Enforce linebreaks in curly braces in JSX attributes and expressions. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-newline.md + 'react/jsx-curly-newline': [ + 'off', + { + multiline: 'consistent', + singleline: 'consistent', + }, + ], + // Enforce or disallow spaces inside of curly braces in JSX attributes + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md + 'react/jsx-curly-spacing': ['error', 'never', { allowMultiline: true }], + // Enforce spacing around jsx equals signs + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-equals-spacing.md + 'react/jsx-equals-spacing': ['error', 'never'], + // DISABLE: only .jsx files may have JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md + 'react/jsx-filename-extension': 'off', + // Require that the first prop in a JSX element be on a new line when the element is multiline + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md + 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'], + // DISABLE: Enforce shorthand or standard form for React fragments + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-fragments.md + 'react/jsx-fragments': ['off', 'syntax'], + // Enforce event handler naming conventions in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md + 'react/jsx-handler-names': [ + 'off', + { + eventHandlerPrefix: 'handle', + eventHandlerPropPrefix: 'on', + }, + ], + // Validate props indentation in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md + 'react/jsx-indent-props': ['error', 2], + // DISABLE for prettier: Enforce JSX indentation + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md + 'react/jsx-indent': ['off', 2], + // Validate JSX has key prop when in array or iterator + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-key.md + 'react/jsx-key': 'error', + // Validate JSX maximum depth + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-depth.md + 'react/jsx-max-depth': 'off', + // Limit maximum of props on a single line in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md + 'react/jsx-max-props-per-line': ['off', { maximum: 1, when: 'multiline' }], + // DISABLED: This is a stylistic rule intended to make JSX code more readable by requiring or preventing lines between adjacent JSX elements and expressions. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-newline.md + 'react/jsx-newline': 'off', + // Prevent usage of .bind() in JSX props + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md + 'react/jsx-no-bind': [ + 'error', + { + ignoreRefs: true, + allowArrowFunctions: true, + allowFunctions: false, + allowBind: false, + ignoreDOMComponents: true, + }, + ], + // prevent accidental JS comments from being injected into JSX as text + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md + 'react/jsx-no-comment-textnodes': 'error', + // This rule prevents non-stable values (i.e. object identities) from being used as a value for Context.Provider. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-constructed-context-values.md + 'react/jsx-no-constructed-context-values': 'error', + // Prevent duplicate props in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md + 'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }], + // Disallow problematic leaked values from being rendered + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-leaked-render.md + 'react/jsx-no-leaked-render': 'error', + // Prevent usage of unwrapped JSX strings + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md + 'react/jsx-no-literals': ['off', { noStrings: true }], + // Disallow target="_blank" on links + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md + 'react/jsx-no-target-blank': ['error', { enforceDynamicLinks: 'always' }], + // Disallow undeclared variables in JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md + 'react/jsx-no-undef': 'error', + // Disallow unnecessary fragments + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md + 'react/jsx-no-useless-fragment': 'error', + // DISABLE for prettier: One JSX Element Per Line + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-one-expression-per-line.md + 'react/jsx-one-expression-per-line': ['off', { allow: 'single-child' }], + // Enforce PascalCase for user-defined JSX components + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md + 'react/jsx-pascal-case': [ + 'error', + { + allowAllCaps: true, + ignore: [], + }, + ], + // Disallow multiple spaces between inline JSX props + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-multi-spaces.md + 'react/jsx-props-no-multi-spaces': 'error', + // Disallow JSX props spreading + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md + 'react/jsx-props-no-spreading': 'off', + // Deprecated in favor of react/jsx-sort-props + 'react/jsx-sort-prop-types': 'off', + // Validate whitespace in and around the JSX opening and closing brackets + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md + 'react/jsx-tag-spacing': [ + 'error', + { + closingSlash: 'never', + beforeSelfClosing: 'always', + afterOpening: 'never', + beforeClosing: 'never', + }, + ], + // Prevent React to be incorrectly marked as unused + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md + 'react/jsx-uses-react': ['error'], + // Prevent variables used in JSX to be incorrectly marked as unused + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md + 'react/jsx-uses-vars': 'error', + // Prevent missing parentheses around multilines JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md + // DISABLE: conflict with prettier + 'react/jsx-wrap-multilines': [ + 'off', + { + 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: 'ignore', + }, + ], + // Prevent using this.state within a this.setState + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-access-state-in-setstate.md + 'react/no-access-state-in-setstate': 'error', + // Prevent adjacent inline elements not separated by whitespace. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md + 'react/no-adjacent-inline-elements': 'off', + // Prevent usage of Array index in keys + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md + 'react/no-array-index-key': 'error', + // Lifecycle methods should be methods on the prototype, not class fields + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-arrow-function-lifecycle.md + 'react/no-arrow-function-lifecycle': 'off', + // Prevent passing of children as props + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md + 'react/no-children-prop': 'error', + // Prevent problem with children and props.dangerouslySetInnerHTML + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md + 'react/no-danger-with-children': 'error', + // Prevent usage of dangerous JSX properties + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger.md + 'react/no-danger': 'warn', + // Prevent usage of deprecated methods + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md + 'react/no-deprecated': ['error'], + // Prevent usage of setState in componentDidMount + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md + // this is necessary for server-rendering + 'react/no-did-mount-set-state': 'off', + // Prevent usage of setState in componentDidUpdate + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md + 'react/no-did-update-set-state': 'error', + // Prevent direct mutation of this.state + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md + 'react/no-direct-mutation-state': 'error', + // warn against using findDOMNode() + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md + 'react/no-find-dom-node': 'error', + // Prevent usage of invalid attributes + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-invalid-html-attribute.md + 'react/no-invalid-html-attribute': 'error', + // Prevent usage of isMounted + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md + 'react/no-is-mounted': 'error', + // Prevent multiple component definition per file + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md + 'react/no-multi-comp': 'off', + // Enforce that namespaces are not used in React elements + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-namespace.md + 'react/no-namespace': 'error', + // Prevent usage of shouldComponentUpdate when extending React.PureComponent + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-redundant-should-component-update.md + 'react/no-redundant-should-component-update': 'error', + // disallow using React.render/ReactDOM.render's return value + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md + 'react/no-render-return-value': 'error', + // Prevent usage of setState + // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-set-state.md + 'react/no-set-state': 'off', + // DISABLE: Prevent using string references + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md + 'react/no-string-refs': 'off', + // Prevent this from being used in stateless functional components + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-this-in-sfc.md + 'react/no-this-in-sfc': 'error', + // Prevents common casing typos + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-typos.md + 'react/no-typos': 'error', + // Prevent invalid characters from appearing in markup + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md + 'react/no-unescaped-entities': 'error', + // Prevent usage of unknown DOM property + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md + 'react/no-unknown-property': 'error', + // Prevent usage of UNSAFE_ methods + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unsafe.md + 'react/no-unsafe': 'off', + // Creating components inside components without memoization leads to unstable components. The nested component and all + // its children are recreated during each re-render. Given stateful children of the nested component will lose their state on each re-render. + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unstable-nested-components.md + 'react/no-unstable-nested-components': ['error', { allowAsProps: false }], + // Prevent declaring unused methods of component class + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-class-component-methods.md + 'react/no-unused-class-component-methods': 'error', + // Prevent unused propType definitions + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-prop-types.md + 'react/no-unused-prop-types': [ + 'error', + { + customValidators: [], + skipShapeProps: true, + }, + ], + // Prevent unused state values + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-state.md + 'react/no-unused-state': 'error', + // Prevent usage of setState in componentWillUpdate + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-will-update-set-state.md + 'react/no-will-update-set-state': 'error', + // Require ES6 class declarations over React.createClass + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md + 'react/prefer-es6-class': ['error', 'always'], + // Prefer exact proptype definitions + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-exact-props.md + 'react/prefer-exact-props': 'warn', + // Enforce that props are read-only + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-read-only-props.md + 'react/prefer-read-only-props': 'off', + // DISABLE: Require stateless functions when not using lifecycle methods, setState or ref + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md + 'react/prefer-stateless-function': 'off', + // Prevent missing props validation in a React component definition + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prop-types.md + // OFF: use typescript + 'react/prop-types': [ + 'off', + { + ignore: [], + customValidators: [], + skipUndeclared: false, + }, + ], + // Prevent missing React when using JSX + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md + 'react/react-in-jsx-scope': 'off', + // Enforce a defaultProps definition for every prop that is not a required prop + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-default-props.md + 'react/require-default-props': 'off', + // require a shouldComponentUpdate method, or PureRenderMixin + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-optimization.md + 'react/require-optimization': ['off', { allowDecorators: [] }], + // Require render() methods to return something + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md + 'react/require-render-return': 'error', + // Prevent extra closing tags for components without children + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md + 'react/self-closing-comp': 'error', + // Enforce propTypes declarations alphabetical sorting + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md + 'react/sort-prop-types': [ + 'off', + { + ignoreCase: true, + callbacksLast: false, + requiredFirst: false, + sortShapeProp: true, + }, + ], + // Enforce state initialization style + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/state-in-constructor.md + 'react/state-in-constructor': ['error', 'never'], + // Enforces where React component static properties should be positioned + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/static-property-placement.md + 'react/static-property-placement': ['error', 'static public field'], + // Require style prop value be an object or var + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md + 'react/style-prop-object': 'error', + // Prevent void DOM elements from receiving children + // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md + 'react/void-dom-elements-no-children': 'error', +}; + +const reactHooksPluginRules = { + // https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js + 'react-hooks/rules-of-hooks': 'error', + // https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js + 'react-hooks/exhaustive-deps': 'warn', +}; + +const nextPluginRules = { + // Enforce font-display behavior with Google Fonts. + // https://nextjs.org/docs/messages/google-font-display + '@next/next/google-font-display': 'warn', + // Ensure preconnect is used with Google Fonts. + // https://nextjs.org/docs/messages/google-font-preconnect + '@next/next/google-font-preconnect': 'warn', + // Prefer next/script component when using the inline script for Google Analytics. + // https://nextjs.org/docs/messages/next-script-for-ga + '@next/next/next-script-for-ga': 'warn', + // Prevent usage of next/script's beforeInteractive strategy outside of pages/_document.js. + // https://nextjs.org/docs/messages/no-before-interactive-script-outside-document + '@next/next/no-before-interactive-script-outside-document': 'warn', + // Prevent manual stylesheet tags. + // https://nextjs.org/docs/messages/no-css-tags + '@next/next/no-css-tags': 'warn', + // Prevent usage of <head> element. + // https://nextjs.org/docs/messages/no-head-element + '@next/next/no-head-element': 'warn', + // Prevent usage of <a> elements to navigate to internal Next.js pages. + // https://nextjs.org/docs/messages/no-html-link-for-pages + '@next/next/no-html-link-for-pages': 'warn', + // Prevent usage of <a> elements to navigate to internal Next.js pages. + // https://nextjs.org/docs/messages/no-html-link-for-pages + '@next/next/no-page-custom-font': 'warn', + // https://nextjs.org/docs/messages/no-styled-jsx-in-document + // Prevent usage of styled-jsx in pages/_document.js. + '@next/next/no-styled-jsx-in-document': 'warn', + // Prevent synchronous scripts. + // https://nextjs.org/docs/messages/no-sync-scripts + '@next/next/no-sync-scripts': 'warn', + // Prevent usage of <title> with Head component from next/document. + // https://nextjs.org/docs/messages/no-title-in-document-head + '@next/next/no-title-in-document-head': 'warn', + // Prevent common typos in Next.js's data fetching functions + '@next/next/no-typos': 'warn', + // Prevent duplicate polyfills from Polyfill.io. + // https://nextjs.org/docs/messages/no-unwanted-polyfillio + '@next/next/no-unwanted-polyfillio': 'warn', + // https://nextjs.org/docs/messages/no-img-element + // Prevent usage of <img> element due to slower LCP and higher bandwidth. + '@next/next/no-img-element': 'off', + // Enforce id attribute on next/script components with inline content. + // https://nextjs.org/docs/messages/inline-script-id + '@next/next/inline-script-id': 'error', + // Prevent assignment to the module variable. + // https://nextjs.org/docs/messages/no-assign-module-variable + '@next/next/no-assign-module-variable': 'error', + // Prevent importing next/document outside of pages/_document.js. + // https://nextjs.org/docs/messages/no-document-import-in-page + '@next/next/no-document-import-in-page': 'error', + // Prevent duplicate usage of <Head> in pages/_document.js. + // https://nextjs.org/docs/messages/no-duplicate-head + '@next/next/no-duplicate-head': 'error', + // Prevent usage of next/head in pages/_document.js. + // https://nextjs.org/docs/messages/no-head-import-in-document + '@next/next/no-head-import-in-document': 'error', + // Prevent usage of next/script in next/head component. + // https://nextjs.org/docs/messages/no-script-component-in-head + '@next/next/no-script-component-in-head': 'error', + // Prevent usage of <a> elements to navigate to internal Next.js pages. + // https://nextjs.org/docs/messages/no-html-link-for-pages + '@next/next/no-html-link-for-pages': 'error', + // Prevent synchronous scripts. + // https://nextjs.org/docs/messages/no-sync-scripts + '@next/next/no-sync-scripts': 'error', +}; + +module.exports = { + reactJSXA11yPluginRules, + reactPluginRules, + reactHooksPluginRules, + nextPluginRules, +}; diff --git a/packages/eslint-ruleset/CHANGELOG.md b/packages/eslint-ruleset/CHANGELOG.md deleted file mode 100644 index 088be3e..0000000 --- a/packages/eslint-ruleset/CHANGELOG.md +++ /dev/null @@ -1,17 +0,0 @@ -# @chotot/eslint-ruleset - -## 1.0.1 - -### Patch Changes - -- 71d19a5: turn on no-unused-var - -## 1.0.0 - -### Major Changes - -- 8cecd4d: init ruleset for sharing between config - -### Minor Changes - -- 8cecd4d: share ruleset diff --git a/packages/eslint-ruleset/package.json b/packages/eslint-ruleset/package.json deleted file mode 100644 index 28515f6..0000000 --- a/packages/eslint-ruleset/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@chotot/eslint-ruleset", - "version": "1.0.1", - "description": "Chotot's Set of Rules for ESLint", - "main": "src/index.js", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/ChoTotOSS/chotot-web-standards", - "directory": "packages/eslint-ruleset" - }, - "files": [ - "src" - ] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2608425..c3bda1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,31 +24,28 @@ importers: specifier: 1.10.0 version: 1.10.0 - packages/eslint-config-bare: + packages/eslint-config-base: dependencies: - '@chotot/eslint-ruleset': - specifier: workspace:* - version: link:../eslint-ruleset '@rushstack/eslint-patch': - specifier: 1.3.2 + specifier: ^1.3.2 version: 1.3.2 '@typescript-eslint/eslint-plugin': - specifier: 5.62.0 + specifier: ^5.62.0 version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.41.0)(typescript@5.0.4) '@typescript-eslint/parser': - specifier: 5.62.0 + specifier: ^5.62.0 version: 5.62.0(eslint@8.41.0)(typescript@5.0.4) eslint: specifier: ^7.23.0 || ^8.0.0 version: 8.41.0 eslint-import-resolver-node: - specifier: 0.3.7 + specifier: ^0.3.7 version: 0.3.7 eslint-import-resolver-typescript: - specifier: 3.5.5 + specifier: ^3.5.5 version: 3.5.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0) eslint-plugin-import: - specifier: 2.27.5 + specifier: ^2.27.5 version: 2.27.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0) typescript: specifier: '>=3.3.1' @@ -56,6 +53,9 @@ importers: packages/eslint-config-next: dependencies: + '@chotot/eslint-config-base': + specifier: workspace:* + version: link:../eslint-config-base '@chotot/eslint-plugin-chotot': specifier: workspace:* version: link:../eslint-plugin-chotot