1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】eslintの設定 備忘録

Last updated at Posted at 2022-02-14

初めに

React では eslint を使うのが一般的になってきています。その際に設定をいちいち考えるのなかなかめんどくさいので、忘備録としてここに残しておきます。
typescript・prettie 対応です。

eslintrc.js

.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'plugin:react/recommended',
    'airbnb',
    'airbnb/hooks',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
    'plugin:cypress/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
    'prettier',
  ],
  globals: {
    cy: 'readonly',
    Cypress: 'readonly',
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    project: './tsconfig.eslint.json',
    sourceType: 'module',
    tsconfigRootDir: __dirname,
  },
  plugins: [
    '@typescript-eslint',
    'import',
    'jsx-a11y',
    'prefer-arrow',
    'react',
    'react-hooks',
    'cypress',
  ],
  root: true,
  rules: {
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': ['error'],
    'lines-between-class-members': [
      'error',
      'always',
      {
        exceptAfterSingleLine: true,
      },
    ],
    'no-void': [
      'error',
      {
        allowAsStatement: true,
      },
    ],
    'padding-line-between-statements': [
      'error',
      {
        blankLine: 'always',
        prev: '*',
        next: 'return',
      },
    ],
    '@typescript-eslint/no-unused-vars': [
      'error',
      {
        vars: 'all',
        args: 'after-used',
        argsIgnorePattern: '_',
        ignoreRestSiblings: false,
        varsIgnorePattern: '_',
      },
    ],
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: [
          '**/setupTests.ts',
          '.storybook/**',
          'stories/**',
          '**/*/*.story.*',
          '**/*/*.stories.*',
          '**/__specs__/**',
          '**/*/*.spec.*',
          '**/__tests__/**',
          '**/*/*.test.*',
        ],
      },
    ],
    'prefer-arrow/prefer-arrow-functions': [
      'error',
      {
        disallowPrototype: true,
        singleReturnOnly: false,
        classPropertiesAllowed: false,
      },
    ],
    'react/jsx-filename-extension': [
      'error',
      {
        extensions: ['.jsx', '.tsx'],
      },
    ],
    'react/jsx-props-no-spreading': [
      'error',
      {
        html: 'enforce',
        custom: 'enforce',
        explicitSpread: 'ignore',
      },
    ],
    'react/react-in-jsx-scope': 'off',
    'react-hooks/rules-of-hooks': 'error',
    'react/require-default-props': [0],
    'react-hooks/exhaustive-deps': [
      'warn',
      {
        additionalHooks: 'useRecoilCallback',
      },
    ],
  },
  overrides: [
    {
      files: ['*.tsx'],
      rules: {
        'react/prop-types': 'off',
      },
    },
  ],
  settings: {
    'import/resolver': {
      node: {
        paths: ['src/'],
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },
};

.eslintignore

.eslintignore
build/
public/
**/coverage/
**/node_modules/
**/*.min.js
*.config.js
.*lintrc.js
.eslintrc.js
cypress/plugins/
cypress/integration/
cypress/support/

.stylelintrc.js

.styleintrc.js
module.exports = {
  extends: ['stylelint-config-standard', 'stylelint-config-recess-order'],
  plugins: ['stylelint-order'],
  ignoreFiles: ['**/node_modules/**'],
  rules: {
    'string-quotes': 'single',
  },
};

.prettierrc

.prettierrc
singleQuote: true
trailingComma: "all"

tsconfig.eslint.json

tsconfig.eslint.json
{
  "extends": "./tsconfig.json",
  "include": [
    "src/**/*.js",
    "src/**/*.jsx",
    "src/**/*.ts",
    "src/**/*.tsx",
  ],
  "exclude": [
    "node_modules"
  ]
}

tsconfig.json

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext",
      "es5"
    ],
    "types": ["jest"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": "src",
    "downlevelIteration": true
  },
  "include": [
    "src",
  ]
}

package.json

package.json
{
  "name": "coffee-oma",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@hookform/error-message": "^2.0.0",
    "@storybook/react": "^6.2.9",
    "@testing-library/jest-dom": "^5.11.10",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^13.0.16",
    "@types/jest": "^26.0.22",
    "@types/node": "^14.14.37",
    "@types/react": "^17.0.3",
    "@types/react-dom": "^17.0.3",
    "@types/react-router": "^5.1.18",
    "@types/react-router-dom": "^5.3.3",
    "@types/recoil": "^0.0.1",
    "axios": "^0.21.1",
    "browserslist": "^4.18.0",
    "dayjs": "^1.10.4",
    "eslint-config-react-app": "^6.0.0",
    "framer-motion": "^4.1.17",
    "history": "5",
    "react": "^17.0.2",
    "react-cookie": "^4.1.1",
    "react-docgen-typescript-webpack-plugin": "^1.1.0",
    "react-dom": "^17.0.2",
    "react-helmet": "^6.1.0",
    "react-hook-form": "^7.4.0",
    "react-loader-spinner": "^4.0.0",
    "react-query": "^3.32.1",
    "react-rating": "^2.0.5",
    "react-router": "6.2.1",
    "react-router-dom": "6.2.1",
    "react-scripts": "4.0.3",
    "react-simple-star-rating": "^4.0.0",
    "recoil": "^0.2.0",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^2.0.3",
    "styled-components": "^5.2.3",
    "typescript": "^4.2.3",
    "use-file-upload": "^1.0.9",
    "use-state-if-mounted": "^1.0.4",
    "web-vitals": "^1.1.1"
  },
  "scripts": {
    "start": "REACT_APP_NODE_ENV=development react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "heroku:start": "react-scripts build && react-scripts start",
    "fix": "npm run -s format && npm run -s lint:fix",
    "format": "prettier --write --loglevel=warn 'src/**/*.{js,jsx,ts,tsx,gql,graphql,json}'",
    "lint": "npm run -s lint:style; npm run -s lint:es",
    "lint:fix": "npm run -s lint:style:fix && npm run -s lint:es:fix",
    "lint:es": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:es:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:conflict": "eslint-config-prettier 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:style": "stylelint 'src/**/*.{css,less,sass,scss}'",
    "lint:style:fix": "stylelint --fix 'src/**/*.{css,less,sass,scss}'",
    "preinstall": "typesync || :",
    "storybool": "start-storybook -p 6006",
    "build:storybook": "build-storybook -o build/stroybook",
    "storybook": "start-storybook -p 6006 -s public",
    "build-storybook": "build-storybook -s public",
    "cypress": "cypress open",
    "cypress:run": "cypress run",
    "start:ci": "CHOKIDAR_USEPOLLING=true react-scripts start",
    "cy:ci": "start-server-and-test start http://localhost:3000 cypress:run"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "overrides": [
      {
        "files": [
          "**/*.stories.*"
        ],
        "rules": {
          "import/no-anonymous-default-export": "off"
        }
      }
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "jest": {
    "resetMocks": false
  },
  "devDependencies": {
    "@storybook/addon-a11y": "^6.2.9",
    "@storybook/addon-actions": "^6.2.9",
    "@storybook/addon-console": "^1.2.3",
    "@storybook/addon-controls": "^6.2.9",
    "@storybook/addon-docs": "^6.2.9",
    "@storybook/addon-essentials": "^6.2.9",
    "@storybook/addon-info": "^5.3.21",
    "@storybook/addon-knobs": "^6.2.9",
    "@storybook/addon-links": "^6.2.9",
    "@storybook/addon-storyshots": "^6.2.9",
    "@storybook/addon-storyshots-puppeteer": "^6.2.9",
    "@storybook/addon-storysource": "^6.2.9",
    "@storybook/addon-viewport": "^6.2.9",
    "@storybook/node-logger": "^6.2.9",
    "@storybook/preset-create-react-app": "^3.1.7",
    "@types/babel-plugin-macros": "^2.8.4",
    "@types/prettier": "^2.2.3",
    "@types/react-helmet": "^6.1.1",
    "@types/react-test-renderer": "^17.0.1",
    "@types/storybook-react-router": "^1.0.1",
    "@types/storybook__addon-actions": "^5.2.1",
    "@types/storybook__addon-info": "^5.2.3",
    "@types/storybook__addon-knobs": "^5.2.1",
    "@types/storybook__react": "^5.2.1",
    "@types/styled-components": "^5.1.9",
    "@types/stylelint": "^9.10.1",
    "@types/testing-library__jest-dom": "^5.9.5",
    "@types/testing-library__user-event": "^4.2.0",
    "@typescript-eslint/eslint-plugin": "^4.20.0",
    "@typescript-eslint/parser": "^4.20.0",
    "axios-mock-adapter": "^1.20.0",
    "babel-loader": "^8.2.2",
    "babel-plugin-macros": "^3.1.0",
    "cypress": "^8.7.0",
    "eslint-config-airbnb": "18.2.1",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-cypress": "^2.12.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prefer-arrow": "^1.2.3",
    "eslint-plugin-react": "^7.23.1",
    "eslint-plugin-react-hooks": "4.2.0",
    "jest": "^27.0.1",
    "jest-localstorage-mock": "^2.4.13",
    "jest-watch-typeahead": "^0.6.4",
    "prettier": "^2.2.1",
    "puppeteer": "^10.0.0",
    "react-docgen-typescript-loader": "^3.7.2",
    "react-test-renderer": "^17.0.2",
    "require-context.macro": "^1.2.2",
    "start-server-and-test": "^1.14.0",
    "storybook-addon-mock": "^0.1.0",
    "storybook-axios": "^1.0.1",
    "storybook-react-router": "^1.0.8",
    "stylelint": "^13.12.0",
    "stylelint-config-recess-order": "^2.3.0",
    "stylelint-config-standard": "^21.0.0",
    "stylelint-order": "^4.1.0",
    "typescript-styled-plugin": "^0.15.0",
    "typesync": "^0.8.0"
  }
}

参考

下記の書籍を読んで学べば、React の事は完全に理解できると思います

りあクト

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?