eslint+typescript+prettier+husky+lint-staged规范前端代码配置
痛点
- 代码可读性低
- 代码规范落地难
- 代码格式难统一
- 代码质量低下
为什么用 eslint不直接用 tslint?
In the TypeScript 2019 Roadmap, the TypeScript core team explains that ESLint has a more performant architecture than TSLint and that they will only be focusing on ESLint when providing editor linting integration for TypeScript. For that reason, I would recommend using ESLint for linting TypeScript projects.
1. 安装 eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin:
yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev
or
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
- eslint: The core ESLint linting library
- @typescript-eslint/parser: ESLint对TypeScript代码进行解析
- @typescript-eslint/eslint-plugin: 包含一组特定的TypeScript的ESLint规则的插件
2. 在项目根目录新建一个配置文件.eslintrc.js。最好不要用.eslintrc.json(.eslintrc.js可以写注释)
.eslintrc.js文件配置module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
},
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
};
如果使用TypeScript + React开发 ,则应该安装eslint-plugin-react 依赖项,可以使用以下配置:
yarn add eslint-plugin-react --dev
or
npm install eslint-plugin-react --save-dev
如果使用react hooks api,则应该安装eslint-plugin-react-hooks 依赖项
yarn add eslint-plugin-react-hooks --dev
or
npm install eslint-plugin-react-hooks --save-dev
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
};
如果使用TypeScript + Vue开发 ,则应该安装eslint-plugin-vue 依赖项,可以使用以下配置:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
'plugin:vue/essential'
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
};
3. Adding Prettier
yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev
or
npm install prettier eslint-config-prettier eslint-plugin-prettier --save-dev
- prettier: The core prettier library
- eslint-config-prettier: Disables ESLint rules that might conflict with prettier
- eslint-plugin-prettier: Runs prettier as an ESLint rule
在项目根目录新建一个配置文件.prettierrc.js。文件配置也可以放到.eslintrc.js中
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2,
};
Next, the .eslintrc.js file needs to be updated:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
},
rules: {
// 自定义 prettier 规则
'prettier/prettier': [
'error',
{
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2
}
]
}
};
The advantage of having prettier setup as an ESLint rule using eslint-plugin-prettier is that code can automatically be fixed using ESLint's --fix option.
4.Automatically Fixing Code (VS Code)
For a good developer experience, it's useful to setup your editor to automatically run ESLint's automatic fix command (i.e. eslint --fix) whenever a file is saved. Since i'm using VS Code, here is the config required in the settings.json file in VS Code to get automatic fixing whenever saving a file:
"eslint.autoFixOnSave": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
If you've also set the editor.formatOnSave option to true in your settings.json, you'll need to add the following config to prevent running 2 formatting commands on save for JavaScript and TypeScript files:
"editor.formatOnSave": true,
"[javascript]": {
"editor.formatOnSave": false,
},
"[javascriptreact]": {
"editor.formatOnSave": false,
},
"[typescript]": {
"editor.formatOnSave": false,
},
"[typescriptreact]": {
"editor.formatOnSave": false,
},
5. 安装husky lint-staged
yarn add husky lint-staged --dev
or
npm install husky lint-staged --save-dev
package.json文件
"scripts": {
"eslint": "eslint src --ext .ts",
"lint": "tsc src/**/*.ts",
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.{ts,tsx,jsx,vue}": [
"prettier --write", // 最好不加
"eslint --fix", //
"git add"
]
},
6. 简单的.eslintrc.js文件配置
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
},
plugins: ['@typescript-eslint', 'react-hooks', 'prettier'],
globals: {
// 这里填入你的项目需要的全局变量
},
rules: {
// 这里填入你的项目需要的个性化配置
// 自定义 prettier 规则
'prettier/prettier': [
'error',
{
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2,
},
],
// 一个缩进必须用两个空格替代
indent: [
'error',
2,
{
SwitchCase: 1,
flatTernaryExpressions: true,
},
],
'react-hooks/rules-of-hooks': 'error', // react hooks校验
'react-hooks/exhaustive-deps': 'warn',
// 禁止使用console
'no-console': 'error',
'no-return-assign': 'warn',
'array-callback-return': 'error',
'guard-for-in': 'off',
'max-len': 'error', // 字符串最大长度
// 类和接口的命名必须遵守帕斯卡命名法,比如 PersianCat
'@typescript-eslint/class-name-casing': 'error',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-var-requires': 'off',
},
};