主要展示了eslint + typescript + react的配置。此外,也有eslint + javascript/typescript的配置。vue的eslint配置可以参考本文章进行配置。
🎁 CV党无需动脑直接配置eslint+typescript+react步骤:
- 安装vsocde-插件: eslint, prettier
- (复制粘贴安装npm包) npm install -g eslint prettier
- (复制粘贴安装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
- 点击settings.json, 复制到vscode编辑器配置settings.json里面
- 终端命令
eslint --init- 选择 To check syntax and find problems, 按enter
- 选择 JavaScript modules, 按enter
- 选择 React或者Vue, 按enter
- 选择使用Typescript选Yes, 使用JavaScript选No, 按enter
- 选择Browser,按enter
- 选择JavaScript,按enter
- 立即npm安装(Yes)
- 点击.eslintrc.json, 复制粘贴到刚刚生成的.eslintrc.json文件当中
- 点击.prettier.json, 复制粘贴到刚刚生成的.prettierrc.json文件当中
- 创建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插件介绍和文档
- import: eslint-plugin-import/no-cycle.md at main · import-js/eslint-plugin-import
- promise: eslint-plugin-promise - npm
- react: eslint-plugin-react - npm
- react-hooks: Rules of Hooks – React
- jsx-ally: jsx-eslint/eslint-plugin-jsx-a11y: Static AST checker for a11y rules on JSX elements.
- typescript: @typescript-eslint/eslint-plugin - npm
- import: eslint-plugin-import/docs/rules at main · import-js/eslint-plugin-import
初始化
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"
}
}