DEV Community

Djamaile
Djamaile

Posted on • Originally published at djamaile.dev

How to setup husky, eslint and prettier within minutes

repository: https://github.com/djamaile/hep-demo

Starting up

Let’s first generate a simple React project by using create-react-app. Execute the following command:

npx create-react-app hep-demo --template typescript && cd hep-demo
Enter fullscreen mode Exit fullscreen mode

Start the app and see if everything is working properly:

yarn start
Enter fullscreen mode Exit fullscreen mode

If you encounter a issue with "babel-jest": "^26.6.0" add a .env file with SKIP_PREFLIGHT_CHECK=true (echo 'SKIP_PREFLIGHT_CHECK=true' > .env )

Installing packages

Now that our app is working we can start by adding the needed packages.
For this setup we would need prettier, husky, lint-staged, eslint-config-airbnb and spotify/prettier-config.
The last one is optional, you can also create your own prettier config but recently
I have been using spotify's config with pleasant results.

To install the packages, execute the following command:

yarn add @spotify/prettier-config @typescript-eslint/parser husky lint-staged prettier -D
Enter fullscreen mode Exit fullscreen mode

We will use the eslint config of airbnb to do that execute the following command:

npx install-peerdeps --dev eslint-config-airbnb
Enter fullscreen mode Exit fullscreen mode

In the root of your project, create a file called .eslintrc.json and add the following content to it:

{
  "extends": [
    "airbnb"
  ],
  "parser": "@typescript-eslint/parser",
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "jest": true,
    "node": true
  },
  "rules": {
    "no-console": "off",
    "import/prefer-default-export": "off",
    "@typescript-eslint/camelcase": ["off"],
    "camelcase": ["off"],
    "react/jsx-props-no-spreading": ["off"],
    "jsx-a11y/no-static-element-interactions": "off",
    "react/prop-types": ["off"],
    "jsx-a11y/href-no-hash": ["off"],
    "jsx-a11y/click-events-have-key-events": ["off"],
    "import/no-unresolved": ["off"],
    "import/extensions": 0,
    "no-use-before-define": "off",
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off",
    "react/jsx-filename-extension": [
      "warn",
      {
        "extensions": [".js", ".jsx", ".tsx", ".ts"]
      }
    ],
    "max-len": [
      "warn",
      {
        "code": 100,
        "tabWidth": 2,
        "comments": 80,
        "ignoreComments": false,
        "ignoreTrailingComments": true,
        "ignoreUrls": true,
        "ignoreStrings": true,
        "ignoreTemplateLiterals": true,
        "ignoreRegExpLiterals": true
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

You, of course, don’t have to use the same rules as mine. Play with it and see what fits you the best!

Configure package json

Once the packages are installed, we can make some changes in our package.json. Let’s first start with some handy scripts:

"scripts": {
    ...
    "prettier:check": "prettier --check .",
    "prettier:write": "prettier --write .",
    "prepare": "husky install"
}
Enter fullscreen mode Exit fullscreen mode

The prettier commands are there to check your code and the prepare script we will use in a bit to set up husky with a pre-commit hook.

But first in your package.json down below you can set prettier to @spotify/prettier-config and under that you can specify the lint-staged section.

"prettier": "@spotify/prettier-config",
"lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{json,md}": [
      "prettier --write"
    ]
}
Enter fullscreen mode Exit fullscreen mode

lint-staged will execute those commands on files that are ready to be committed. Basically, it will run its specified linter on all staged git files. But before that is possible, we need to make sure that husky triggers lint-staged.

In the root of your project run:

yarn prepare
Enter fullscreen mode Exit fullscreen mode

Which will create the .husky folder in your project and after we can install a pre-commit hook:

npx husky add .husky/pre-commit "yarn lint-staged" 
Enter fullscreen mode Exit fullscreen mode

This will create a pre-commit hook in the .husky folder. If we inspect the contents of the file you can see that it will run yarn lint-staged.

Ignore files

Before we can test if it works, we should also create .ignore files for prettier and eslint. We don't want to end up scanning the node_modules folder! Create the files:

touch .eslintignore
touch .prettierignore
Enter fullscreen mode Exit fullscreen mode

In both of the files you can add the same folders to ignore:

**/node_modules/**
**/build/**
**/dist/**
**/.git/**
**/public/**
Enter fullscreen mode Exit fullscreen mode

Testing

Now we can actually test if our setup works! First, we’ll need to set up a git for our project:

git init
git add .
git commit -m "first commit"
Enter fullscreen mode Exit fullscreen mode

After you try to commit, you can see husky in action. It will execute yarn lint-staged which in turns calls prettier and eslint for our git staged files.

To see if it works on new stuff, let’s create a file called Button.tsx in the src directory. Once you have done that, add the following code to it:

import React from 'react';

interface Props {
  size: string;
}

export const Button: React.FC<Props> = ({size}) => {
  size = 'big'; return <button>{size}</button>;
};
Enter fullscreen mode Exit fullscreen mode

So, this piece of code is wrong but let eslint tell us why. Add the file and try to commit it:

git add .
git commit -m "feat: add button component"
Enter fullscreen mode Exit fullscreen mode

If eslint is working well you should receive this error:

 error  Assignment to function parameter 'size'      no-param-reassign

 error  Missing an explicit type attribute for button  react/button-has-type

Enter fullscreen mode Exit fullscreen mode

Seems like we have some errors, so let’s fix them before committing our button. Overwrite Button.tsx with the fixed code:

import React from 'react';

interface Props {
  size: string;
}

export const Button: React.FC<Props> = ({ size }) => {
  const rightSize = size ? 'big' : 'small'; return <button type="button">{rightSize}</button>;
};
Enter fullscreen mode Exit fullscreen mode

The code now looks good, but the styling might look a bit off. But that is okay. We are going to let prettier handle that. Let’s try again to add and commit our Button component.

git add .
git commit -m "feat: add button component"
Enter fullscreen mode Exit fullscreen mode

Now we should be greeted by green light and that our component is commited! In addition, if we look at the button component we can see that prettier has rewritten our component, to make it look nicer!

import React from 'react';

interface Props {
  size: string;
}

export const Button: React.FC<Props> = ({ size }) => {
  const rightSize = size ? 'big' : 'small';
  return <button type="button">{rightSize}</button>;
};
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
capaj profile image
Jiri Spac • Edited

I was so lazy to do this on each project I created a CLI util to do this for me: npmjs.com/package/be-pretty

but this only adds prettier, not eslint.

Collapse
 
djamaile profile image
Djamaile

Nice!