なかなかクリーンかもしれないオレオレeslintrc.js

2022/09/24

最終更新:2023/04/12

  • eslint
  • typescript-eslint
  • eslint-plugin-react
  • eslint-plugin-react-hooks
  • eslint-plugin-jsx-a11y

上記のrulesを3連休2日目にしてレコメンドもそれ以外も全て読み切り、自分の好みで設定した。

それぞれ理由含めて書きたいけどとんでもない量になりそうなのでいくつかピックアップしてLT会かなんかで話そうと思う。

eslintrc.js

GitHub

/** @type {import('eslint/lib/shared/types').ConfigData} */
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  parserOptions: {
    tsconfigRootDir: __dirname,
    project: ["./tsconfig.json"],
    ecmaVersion: "latest",
  },
  settings: {
    react: {
      version: "detect",
    },
  },
  extends: [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "plugin:@typescript-eslint/strict",
    "plugin:jsx-a11y/recommended",
    "prettier",
  ],
  rules: {
    "no-constant-binary-expression": "error",
    "no-constructor-return": "error",
    "no-self-compare": "error",
    "no-template-curly-in-string": "error",
    "no-unmodified-loop-condition": "error",
    "arrow-body-style": ["error", "as-needed"],
    complexity: ["error", { max: 8 }],
    "default-case": "error",
    "default-case-last": "error",
    eqeqeq: "error",
    "func-style": ["error", "declaration", { allowArrowFunctions: true }],
    "max-classes-per-file": ["error", 1],
    "max-lines": [
      "error",
      { max: 1000, skipComments: true, skipBlankLines: true },
    ],
    "max-lines-per-function": [
      "error",
      { max: 300, skipComments: true, skipBlankLines: true },
    ],
    "max-params": ["error", 3],
    "no-alert": "error",
    "no-else-return": ["error", { allowElseIf: false }],
    "no-eval": "error",
    "no-floating-decimal": "error",
    "no-inline-comments": "error",
    "no-multi-assign": "error",
    "no-nested-ternary": "error",
    "no-plusplus": ["error", { allowForLoopAfterthoughts: true }],
    "no-unneeded-ternary": "error",

    "object-shorthand": "error",
    "prefer-arrow-callback": "error",
    "prefer-destructuring": "error",
    "prefer-object-spread": "error",
    "prefer-template": "error",
    yoda: "error",

    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-empty-interface": "off",

    "@typescript-eslint/consistent-type-definitions": ["warn", "type"],
    "@typescript-eslint/method-signature-style": "warn",
    "@typescript-eslint/no-confusing-void-expression": "warn",
    "@typescript-eslint/no-require-imports": "warn",
    "@typescript-eslint/require-array-sort-compare": "warn",
    "@typescript-eslint/switch-exhaustiveness-check": "warn",
    "@typescript-eslint/default-param-last": "warn",
    "@typescript-eslint/no-duplicate-imports": "warn",

    "react/prop-types": "off",
    "react/boolean-prop-naming": [
      "warn",
      { rule: "^(is|has)[A-Z]([A-Za-z0-9]?)+" },
    ],
    "react/button-has-type": ["warn"],
    "react/destructuring-assignment": ["error", "never"],
    "react/function-component-definition": [
      "warn",
      {
        namedComponents: "arrow-function",
        unnamedComponents: "arrow-function",
      },
    ],
    "react/hook-use-state": "warn",
    "react/no-unstable-nested-components": ["warn", { allowAsProps: true }],
    "react/self-closing-comp": [
      "error",
      {
        component: true,
        html: true,
      },
    ],
    "react/void-dom-elements-no-children": "error",
    "react/jsx-boolean-value": ["warn", "never"],
    "react/jsx-curly-brace-presence": [
      "warn",
      { props: "never", children: "never", propElementValues: "always" },
    ],
    "react/jsx-fragments": ["error"],
    "react/jsx-handler-names": ["error"],
    "react/jsx-max-depth": ["error", { max: 20 }],
    "react/jsx-no-constructed-context-values": "warn",
    "react/jsx-no-useless-fragment": ["error", { allowExpressions: true }],
    "react/jsx-pascal-case": [
      "error",
      { allowNamespace: true, allowLeadingUnderscore: true },
    ],
    "react/jsx-props-no-spreading": [
      "error",
      {
        html: "ignore",
        custom: "enforce",
      },
    ],
    "jsx-a11y/control-has-associated-label": ["warn"],
  },
}

このブログに設定してみる

該当commit

24とまあまあの差分ファイルとなった。next公式のrulesとの重複は除いている。

もう少しコード量があるプロダクトに入れてチューニングしていきたい。

そしてクリーンかどうかも確かめていきたい。

by me a coffee