DEV Community

loading...

Adding ESLint to Webpack with React and TypeScript

Alexi Taylor 🐢
Hello πŸ‘‹. I'm a Software Engineer, building useful and beautiful things. πŸš€.
・Updated on ・4 min read

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

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.
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.
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 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"
    ]
  }

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.

Extra Resouces:

Happy Coding πŸš€

Discussion (3)

Collapse
igoradamenko profile image
Igor Adamenko • Edited

You don't need git add in the latest version of lint-staged, btw: github.com/okonet/lint-staged#v10

Anyway, thanks, I didn't know about the practice of running ESLint using webpack. Quite surprised!

(But I'm just curious, what does r in lint:r mean?)

Collapse
alexi_be3 profile image
Alexi Taylor 🐢 Author • 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
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.