Background
When working in a team of developers, it is best to have a standard code style. ESLint allows developers to adhere to those basic code conventions by enforcing the same rules and making your code look unified. This helps with maintaining a readable codebase for all developers and avoid any code 💩 smells. ESLint allows you to set up and enforce these rules across the codebase.
Note
With TypeScript, there are 2 linting solutions: 1. ESLint and 2. TSLint. The TypeScript team has highlighted in their roadmap that they will be focusing their efforts on ESLint rather than TSLint where they state:
ESLint already has the more-performant architecture... we'll be switching the TypeScript repository over to using ESLint... - Source
Setting up ESLint with Webpack and TypeScript
- Install dependencies:
npm install eslint
Add Dependencies
- Install dev dependencies:
- eslint-loader : eslint webpack loader
- @typescript-eslint/parser : The parser that will allow ESLint to lint TypeScript code
- @typescript-eslint/eslint-plugin : A plugin that contains ESLint rules that are TypeScript specific
- eslint-plugin-react : React specific linting rules for ESLint
npm install -D eslint-loader @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react
Add ESLint to Webpack configs
- Update your
webpack.config.js
file with:- This will configure ESLInt as part of the Webpack's build process with
eslint-loader
. After each build, any ESLint errors or warnings will be logged in your terminal with ESLint errors preventing your app to compile.
- This will configure ESLInt as part of the Webpack's build process with
rules: [
/**
* ESLINT
* First, run the linter.
* It's important to do this before Babel processes the JS.
* Only testing .ts and .tsx files (React code)
*/
{
test: /\.(ts|tsx)$/,
enforce: 'pre',
use: [
{
options: {
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
exclude: /node_modules/,
},
]
Add ESLint configuration file
- Create an
.eslintrc.js
config file:-
Note: By creating a JavaScript file instead of a JSON file (
.eslintrc
) we can add comments for other developers.
-
Note: By creating a JavaScript file instead of a JSON file (
touch .eslintrc.js
- Add ESLint rules to
.eslintrc.js
:
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
},
},
};
Adding pre-commit hook with ESLint
To avoid 💩 code slipping in your codebase, pre-commit checks can be used to lint your code and check for ESLint errors and warnings before each commit (git commit
). We will configure lint-staged
and husky
to run ESLint during the pre-commit
check.
- Install dev-dependencies:
npm i -D husky lint-staged
- Add ESLint scripts to
package.json
file:-
npm run lint
: will lint.ts
and.tsx
files -
npm run lint:fix
: will lint.ts
and.tsx
files AND automatically fix any minor ESLint issues.
-
"scripts": {
"lint": "eslint --ext .ts,.tsx",
"lint:fix": "npm run lint -- --fix"
}
- Add
husky
andlint-staged
configs topackaged.json
:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"app/**/*.(ts|tsx)": [
"npm run --silent lint:fix",
"git add"
]
}
During the pre-commit hook check, ESLint will fix any minor linting issues and add those changes directly to the current commit. If ESLint problems persist, lint-staged
will prevent the commit from being made and log the ESLint errors and warnings to the console allowing for manual fixes.
Updates:
In v10 and later of lint-staged, we do not need to add git add
in our lint-staged task. From lint-staged docs:
From v10.0.0 onwards any new modifications to originally staged files will be automatically added to the commit. If your task previously contained a git add step, please remove this. The automatic behaviour ensures there are less race-conditions, since trying to run multiple git operations at the same time usually results in an error. -- Source
So we can remove the git add
step:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"app/**/*.(ts|tsx)": [
"npm run --silent lint:fix"
]
}
Thank you Igor Adamenko for catching this.
Top comments (5)
Thank you for catching that change from lint-staged. I added an update section.
In our team we have several linting scripts, the
lint:r
was to lint any React related code.Looks like eslint-loader is deprecated.
Why check the code during build process? Isn't it enough lint it before commit?
I think it's for when working in live development mode. SO maybe put in in your dev webpack config, and omit in prod config
Great! Also, it's mandatory to have the most beloved document named Style Guide among the best devs. BEM should be devoted as well.