简单直接配置eslint vscode

1,748 阅读6分钟

主要展示了eslint + typescript + react的配置。此外,也有eslint + javascript/typescript的配置。vue的eslint配置可以参考本文章进行配置。

🎁 CV党无需动脑直接配置eslint+typescript+react步骤:

  1. 安装vsocde-插件: eslint, prettier
  2. (复制粘贴安装npm包) npm install -g eslint prettier
  3. (复制粘贴安装npm包) npm install -D eslint-plugin-prettier eslint-config-prettier eslint-config-airbnb eslint-plugin-import eslint-import-resolver-webpack eslint-import-resolver-typescript @typescript-eslint/eslint-plugin eslint-plugin-promise eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
  4. 点击settings.json, 复制到vscode编辑器配置settings.json里面
  5. 终端命令eslint --init
    1. 选择 To check syntax and find problems, 按enter
    2. 选择 JavaScript modules, 按enter
    3. 选择 React或者Vue, 按enter
    4. 选择使用Typescript选Yes, 使用JavaScript选No, 按enter
    5. 选择Browser,按enter
    6. 选择JavaScript,按enter
    7. 立即npm安装(Yes)
  6. 点击.eslintrc.json, 复制粘贴到刚刚生成的.eslintrc.json文件当中
  7. 点击.prettier.json, 复制粘贴到刚刚生成的.prettierrc.json文件当中
  8. 创建tsconfig.json文件,点击tsconfig.json, 复制粘贴到自建的tsconfig.json文件当中

vscode-插件

eslint prettier

npm-软件包

eslint & prettier

  • eslint
  • prettier

安装命令

npm i -g eslint npm i -g prettier

插件

按照自己的需要安装插件

  • eslint + typescript + react
  • eslint + javascript
  • eslint + typescript

eslint + typescript + react

  • eslint-plugin-prettier
  • eslint-config-prettier
  • eslint-config-airbnb
  • eslint-plugin-import
  • eslint-import-resolver-webpack
  • eslint-import-resolver-typescript
  • @typescript-eslint/eslint-plugin
  • eslint-plugin-promise
  • eslint-plugin-react
  • eslint-plugin-react-hooks
  • eslint-plugin-jsx-a11y

安装命令

npm install -D eslint-plugin-prettier eslint-config-prettier eslint-config-airbnb eslint-plugin-import eslint-import-resolver-webpack eslint-import-resolver-typescript @typescript-eslint/eslint-plugin eslint-plugin-promise eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y

eslint + javascript

  • eslint-plugin-prettier
  • eslint-config-prettier
  • eslint-config-airbnb
  • eslint-plugin-import
  • eslint-import-resolver-webpack
  • eslint-plugin-promise

安装命令

npm install -D eslint-plugin-prettier eslint-config-prettier eslint-config-airbnb eslint-plugin-import eslint-import-resolver-webpack eslint-plugin-promise

eslint + typescript

  • eslint-plugin-prettier
  • eslint-config-prettier
  • eslint-config-airbnb
  • eslint-plugin-import
  • eslint-import-resolver-typescript
  • @typescript-eslint/eslint-plugin
  • eslint-import-resolver-webpack
  • eslint-plugin-promise

安装命令

npm install -D eslint-plugin-prettier eslint-config-prettier eslint-config-airbnb eslint-plugin-import eslint-import-resolver-typescript @typescript-eslint/eslint-plugin eslint-import-resolver-webpack eslint-plugin-promise

风格规范、eslint插件介绍和文档

风格规范

eslint插件介绍和文档

初始化

eslint --init

prettier

官网 What is Prettier? · Prettier

配置文件

按照自己的需要复制配置文件(❗settings.json以及.prettierrc.json是相同的) 💡只需要选择不同的.eslintrc.json即可

  • eslint + typescript + react
  • eslint + javascript
  • eslint + typescript

settings.json (vscode eslint和prettier全局配置)

{
    // vscode-settings.json
    // eslint
  "eslint.enable": true,
  "eslint.debug": true,
  "eslint.run": "onSave",

  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescriptreact",
    "typescript"
  ],

  //prettier
  "editor.formatOnSave": true,
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  // jsx配置
  "prettier.jsxBracketSameLine": true,
  "prettier.jsxSingleQuote": true
}

.prettierrc.json

{
    "tabWidth": 2,
    "semi": false,
    "singleQuote": false,
    "jsxSingleQuote": false,
    "trailingComma": "none",
    "bracketSpacing": true,
    "bracketSameLine": false,
    "arrowParens": "always"
}

.eslintrc.json

.eslintrc.json(eslint + typescript + react)

{
  "env": {
    "browser": true,
    "node": true,
    "es2021": true
  },
  "extends": [
    "airbnb",
    "plugin:import/recommended",
    "plugin:import/typescript",
    "plugin:promise/recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "plugin:jsx-a11y/recommended",
    "plugin:prettier/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "rules": {
    "no-underscore-dangle": "off",
    "no-unused-vars": [
      "off",
      {
        "ignoreRestSiblings": true,
        "argsIgnorePattern": "res|next|^err"
      }
    ],
    "prefer-const": [
      "error",
      {
        "destructuring": "all"
      }
    ],
    "no-shadow": [
      "off",
      {
        "hoist": "all",
        "allow": ["resolve", "reject", "done", "next", "err", "error"]
      }
    ],
    "radix": "error",
    "no-unused-expressions": [
      "error",
      {
        "allowTaggedTemplates": true
      }
    ],

    "quotes": [
      "error",
      "double",
      {
        "avoidEscape": true,
        "allowTemplateLiterals": true
      }
    ],

    "comma-dangle": [
      "error",
      {
        "arrays": "never",
        "objects": "never",
        "imports": "never",
        "exports": "never",
        "functions": "never"
      }
    ],

    "func-names": ["error", "never"],
    "arrow-body-style": ["warn", "as-needed"],
    "no-param-reassign": [
      "error",
      {
        "props": false
      }
    ],
    "default-param-last": "off",
    "consistent-return": "off",
    "no-return-assign": ["error", "except-parens"],

    "space-before-function-paren": [
      "error",
      { "anonymous": "always", "named": "never", "asyncArrow": "always" }
    ],
    "no-multi-spaces": "error",

    "no-restricted-syntax": [
      "error",
      "ForInStatement",
      "LabeledStatement",
      "WithStatement"
    ],

    "no-await-in-loop": "error",
    "no-debugger": "error",
    "no-alert": "error",
    "no-console": "warn",

    "max-len": "off",

    "import": "off",
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": ["**/*.stories.*", "**/.storybook/**/*.*"],
        "peerDependencies": true
      }
    ],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "json": "always",
        "ts": "never",
        "tsx": "never",
        "less": "never "
      }
    ],
    "import/prefer-default-export": "warn",
    "import/no-unresolved": "off",

    "react/jsx-filename-extension": [
      "warn",
      {
        "extensions": [".js", ".jsx", ".ts", ".tsx", ".mdx"]
      }
    ],

    "react/jsx-pascal-case": ["error"],

    "react/react-in-jsx-scope": "error",

    "react/jsx-closing-bracket-location": ["warn", "tag-aligned"],

    "react/jsx-props-no-spreading": "off",
    "react/no-array-index-key": "error",
    "react/jsx-boolean-value": ["error", "never"],

    "react/no-string-refs": ["error", { "noTemplateLiterals": true }],

    "react/self-closing-comp": "error",

    "react/jsx-curly-spacing": [
      "off",
      { "when": "never", "allowMultiline": false, "chidren": true }
    ],
    "react/jsx-tag-spacing": [
      "error",
      {
        "closingSlash": "never",
        "beforeSelfClosing": "always",
        "afterOpening": "never",
        "beforeClosing": "allow"
      }
    ],

    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "react/function-component-definition": [
      "warn",
      {
        "namedComponents": "arrow-function",
        "unnamedComponents": "arrow-function"
      }
    ],

    "jsx-a11y/accessible-emoji": "warn",
    "jsx-a11y/label-has-associated-control": [
      "error",
      {
        "assert": "either"
      }
    ],
    "jsx-a11y/href-no-hash": "off",
    "jsx-a11y/anchor-is-valid": [
      "warn",
      {
        "aspects": ["invalidHref"]
      }
    ],

    // use React.FC to lint type of  defautlProps instead of using react/prop-types
    "react/prop-types": "off", // Since we do not use prop-types
    "react/require-default-props": "off", // Since we do not use prop-types

    "prettier/prettier": [
      "error",
      {
        "trailingComma": "none",
        "singleQuote": false,
        "printWidth": 80,
        "endOfLine": "auto"
      }
    ],

    "no-void": ["error", { "allowAsStatement": true }],

    "@typescript-eslint/no-floating-promises": [
      "warn",
      {
        "ignoreVoid": true,
        "ignoreIIFE": true
      }
    ],
    "@typescript-eslint/no-extra-semi": "warn"
  },
  "plugins": [
    "import",
    "promise",
    "react",
    "react-hooks",
    "jsx-a11y",
    "prettier",
    "@typescript-eslint"
  ],
  "settings": {
    "import/parsers": {
      "@typescript-eslint/parser": [".ts", ".tsx"]
    },
    "import/resolver": {
      "typescript": {},
      "webpack": {}
    }
  }
}

.eslintrc.json(eslint + typescript)

{
  "env": {
    "browser": true,
    "node": true,
    "es2021": true
  },
  "extends": [
    "airbnb",
    "plugin:import/recommended",
    "plugin:import/typescript",
    "plugin:promise/recommended",
    "plugin:prettier/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "rules": {
    "no-underscore-dangle": "off",
    "no-unused-vars": [
      "off",
      {
        "ignoreRestSiblings": true,
        "argsIgnorePattern": "res|next|^err"
      }
    ],
    "prefer-const": [
      "error",
      {
        "destructuring": "all"
      }
    ],
    "no-shadow": [
      "off",
      {
        "hoist": "all",
        "allow": ["resolve", "reject", "done", "next", "err", "error"]
      }
    ],
    "radix": "error",
    "no-unused-expressions": [
      "error",
      {
        "allowTaggedTemplates": true
      }
    ],

    "quotes": [
      "error",
      "double",
      {
        "avoidEscape": true,
        "allowTemplateLiterals": true
      }
    ],

    "comma-dangle": [
      "error",
      {
        "arrays": "never",
        "objects": "never",
        "imports": "never",
        "exports": "never",
        "functions": "never"
      }
    ],

    "func-names": ["error", "never"],
    "arrow-body-style": ["warn", "as-needed"],
    "no-param-reassign": [
      "error",
      {
        "props": false
      }
    ],
    "default-param-last": "off",
    "consistent-return": "off",
    "no-return-assign": ["error", "except-parens"],

    "space-before-function-paren": [
      "error",
      { "anonymous": "always", "named": "never", "asyncArrow": "always" }
    ],
    "no-multi-spaces": "error",

    "no-restricted-syntax": [
      "error",
      "ForInStatement",
      "LabeledStatement",
      "WithStatement"
    ],

    "no-await-in-loop": "error",
    "no-debugger": "error",
    "no-alert": "error",
    "no-console": "warn",

    "max-len": "off",

    "import": "off",
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": ["**/*.stories.*", "**/.storybook/**/*.*"],
        "peerDependencies": true
      }
    ],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "json": "always",
        "ts": "never",
        "tsx": "never",
        "less": "never "
      }
    ],
    "import/prefer-default-export": "warn",
    "import/no-unresolved": "off",

    "prettier/prettier": [
      "error",
      {
        "trailingComma": "none",
        "singleQuote": false,
        "printWidth": 80,
        "endOfLine": "auto"
      }
    ],

    "no-void": ["error", { "allowAsStatement": true }],

    "@typescript-eslint/no-floating-promises": [
      "warn",
      {
        "ignoreVoid": true,
        "ignoreIIFE": true
      }
    ],
    "@typescript-eslint/no-extra-semi": "warn"
  },
  "plugins": [
    "import",
    "promise",
    "prettier",
    "@typescript-eslint"
  ],
  "settings": {
    "import/parsers": {
      "@typescript-eslint/parser": [".ts", ".tsx"]
    },
    "import/resolver": {
      "typescript": {},
      "webpack": {}
    }
  }
}

.eslintrc.json(eslint + javascript)

{
  "env": {
    "browser": true,
    "node": true,
    "es2021": true
  },
  "extends": [
    "airbnb",
    "plugin:import/recommended",
    "plugin:promise/recommended",
    "plugin:prettier/recommended",
  ],
  "parser": "@babel/eslint-parser",
  "parserOptions": {
    "requireFile": false,
  },
  "rules": {
    "no-underscore-dangle": "off",
    "no-unused-vars": [
      "off",
      {
        "ignoreRestSiblings": true,
        "argsIgnorePattern": "res|next|^err"
      }
    ],
    "prefer-const": [
      "error",
      {
        "destructuring": "all"
      }
    ],
    "no-shadow": [
      "off",
      {
        "hoist": "all",
        "allow": ["resolve", "reject", "done", "next", "err", "error"]
      }
    ],
    "radix": "error",
    "no-unused-expressions": [
      "error",
      {
        "allowTaggedTemplates": true
      }
    ],

    "quotes": [
      "error",
      "double",
      {
        "avoidEscape": true,
        "allowTemplateLiterals": true
      }
    ],

    "comma-dangle": [
      "error",
      {
        "arrays": "never",
        "objects": "never",
        "imports": "never",
        "exports": "never",
        "functions": "never"
      }
    ],

    "func-names": ["error", "never"],
    "arrow-body-style": ["warn", "as-needed"],
    "no-param-reassign": [
      "error",
      {
        "props": false
      }
    ],
    "default-param-last": "off",
    "consistent-return": "off",
    "no-return-assign": ["error", "except-parens"],

    "space-before-function-paren": [
      "error",
      { "anonymous": "always", "named": "never", "asyncArrow": "always" }
    ],
    "no-multi-spaces": "error",

    "no-restricted-syntax": [
      "error",
      "ForInStatement",
      "LabeledStatement",
      "WithStatement"
    ],

    "no-await-in-loop": "error",
    "no-debugger": "error",
    "no-alert": "error",
    "no-console": "warn",

    "max-len": "off",

    "import": "off",
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": ["**/*.stories.*", "**/.storybook/**/*.*"],
        "peerDependencies": true
      }
    ],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "json": "always",
        "ts": "never",
        "tsx": "never",
        "less": "never "
      }
    ],
    "import/prefer-default-export": "warn",
    "import/no-unresolved": "off",

    "prettier/prettier": [
      "error",
      {
        "trailingComma": "none",
        "singleQuote": false,
        "printWidth": 80,
        "endOfLine": "auto"
      }
    ],

    "no-void": ["error", { "allowAsStatement": true }],

  },
  "plugins": [
    "import",
    "promise",
    "prettier",
  ],
  "settings": {
    "import/resolver": {
      "typescript": {},
      "webpack": {}
    }
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "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"
  }
}

推荐资料