DEV Community

Alexi Taylor 🐶
Alexi Taylor 🐶

Posted on • Edited on

Adding ESLint to Webpack with React and TypeScript

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
Enter fullscreen mode Exit fullscreen mode

Add Dependencies

npm install -D eslint-loader @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react
Enter fullscreen mode Exit fullscreen mode

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.
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/,
  },
]
Enter fullscreen mode Exit fullscreen mode

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.
touch .eslintrc.js
Enter fullscreen mode Exit fullscreen mode
  • 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
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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"
}
Enter fullscreen mode Exit fullscreen mode
  • Add husky and lint-staged configs to packaged.json:
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "app/**/*.(ts|tsx)": [
      "npm run --silent lint:fix",
      "git add"
    ]
  }
Enter fullscreen mode Exit fullscreen mode

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"
    ]
  }
Enter fullscreen mode Exit fullscreen mode

Thank you Igor Adamenko for catching this.

Extra Resouces:

Happy Coding 🚀

Top comments (5)

Collapse
 
alexi_be3 profile image
Alexi Taylor 🐶 • Edited

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.

Collapse
 
vishal1419 profile image
Vishal Sherathiya

Looks like eslint-loader is deprecated.

Collapse
 
wenjoy profile image
wenJoy

Why check the code during build process? Isn't it enough lint it before commit?

Collapse
 
strongunsullied profile image
Kasope Johnson

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

Collapse
 
cesarkohl profile image
Cesar Kohl

Great! Also, it's mandatory to have the most beloved document named Style Guide among the best devs. BEM should be devoted as well.