Pain points
- Low readability code
- Code specifications are difficult to implement
- The code format is difficult to unify
- Poor code quality
Why use ESLint instead of tsLint directly?
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. Install 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
Copy the code
- eslint: The core ESLint linting library
- @typescript-eslint/parser: ESLint parses typescript code
- @typescript-eslint/eslint-plugin: A plugin that contains a set of typescript-specific ESLint rules
2. Create a configuration file. Eslintrc.js in the project root directory. It’s best not to use.eslintrc.json(.eslintrc.js can write comments)
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",}};Copy the code
yarn add eslint-plugin-react --dev
or
npm install eslint-plugin-react --save-dev
Copy the code
yarn add eslint-plugin-react-hooks --dev
or
npm install eslint-plugin-react-hooks --save-dev
Copy the code
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
},
},
};
Copy the code
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
},
},
};
Copy the code
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
Copy the code
- ==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
== Create a configuration file in the root directory of the project.prettierrc.js File configuration can also be placed in.eslintrc.js ==
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true.printWidth: 120,
tabWidth: 2,
};
Copy the code
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 configurationin the extends array.
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows forThe use of imports}, rules: {// Customize prettier rule'prettier/prettier': [
'error',
{
semi: true,
trailingComma: 'all',
singleQuote: true.printWidth: 120,
tabWidth: 2
}
]
}
};
Copy the code
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"].Copy the code
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,},Copy the code
5. Install Husky Lint-staged
yarn add husky lint-staged --dev
or
npm install husky lint-staged --save-dev
Copy the code
Package. The json file
"scripts": {
"eslint": "eslint src --ext .ts"."lint": "tsc src/**/*.ts"."precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.{ts,tsx,jsx,vue}": [
"prettier --write"// It is better not to add"eslint --fix", / /"git add"]},Copy the code
6. Simple.eslintrc.js file configuration
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 configurationin 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: {// Fill in the global variables your project needs here}, rules: {// Fill in the personalization of your project here // Customize the prettier rule'prettier/prettier': [
'error',
{
semi: true,
trailingComma: 'all',
singleQuote: true.printWidth: 120, tabWidth: 2,},], // An indent must be replaced by two Spaces: ['error',
2,
{
SwitchCase: 1,
flatTernaryExpressions: true],},'react-hooks/rules-of-hooks': 'error'// React hooks check'react-hooks/exhaustive-deps': 'warn'// Disable console'no-console': 'error'.'no-return-assign': 'warn'.'array-callback-return': 'error'.'guard-for-in': 'off'.'max-len': ['error', {code: 120}], // Maximum string length // Class and interface names must comply with PASCAL naming methods such as 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',}};Copy the code