Article originally posted on my blog.
Recently, I noticed that there were repetitive tasks that I was doing for all the new projects. So, I decided to document them so as not to repeat the mistakes. This article is about setting up Prettier, ESLint, Husky in your project.
This article can help you with:
- Keeping your code clean.
- Following standard practices in your code.
- Ensuring that all the tests pass before commit.
- Improving commit quality by adhering to the conventional commit format.
Steps to setup
- Create a React app any way you like. I prefer to do it with
NPX
.
For TypeScript project:
npx create-react-app my-app --template typescript
For JavaScript project:
npx create-react-app my-app
You can also use Yarn
or NPM
. You can check out CRA docs for more details.
Open the project:
cd my-app
.Installing dependencies:
With TypeScript:
yarn add -D eslint eslint-plugin-react prettier eslint-plugin-jest eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser husky @commitlint/{config-conventional,cli}
The versions of packages at the time of writing are:
{
"devDependencies": {
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"eslint": "^7.32.0",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^7.0.1",
"prettier": "^2.3.2"
}
}
With JavaScript:
yarn add -D eslint eslint-plugin-react prettier eslint-plugin-jest eslint-plugin-react-hooks husky @commitlint/{config-conventional,cli}
The versions of dependencies at the time of writing are:
{
"devDependencies": {
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"eslint": "^7.32.0",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^7.0.1",
"prettier": "^2.3.2"
}
}
- Add Prettier config: create
.prettierrc
with this content. Also, install the Prettier plugin in VSCode.
{
"singleQuote": true,
"jsxBracketSameLine": false,
"useTabs": false,
"eslintIntegration": false,
"tslintIntegration": true,
"requireConfig": false,
"stylelintIntegration": false,
"arrowParens": "always",
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": true,
"tsxSingleQuote": true,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"tabWidth": 2,
"trailingComma": "es5"
}
Note: I prefer this config, you can use Playground and choose what works for you. You can check out the rationale and the options to understand the rules better.
- Add ESLint config: create
.eslintrc.json
with this config. Also, install the ESLint plugin in VSCode.
For TypeScript:
{
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {
"no-bitwise": 0,
"react/react-in-jsx-scope": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off"
}
}
For JavaScript:
{
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"es2021": true,
"node": true,
"jest": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {
"no-bitwise": 0,
"react/react-in-jsx-scope": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}
The rules I have used are basically to override the recommended settings. The only addition being the rules of hooks.
Note: Again, these are rules that I prefer, you can add the ones that work for you. You can check ESLint configuration docs to create your rules.
- Add scripts to
package.json
For TypeScript:
{
"scripts": {
"lint": "eslint \"**/*.{ts,tsx,js,jsx}\"",
"prepare": "husky install",
"test": "react-scripts test"
}
}
For JavaScript:
{
"scripts": {
"lint": "eslint \"**/*.{js,jsx}\"",
"prepare": "husky install",
"test": "react-scripts test"
}
}
- Resolve lint errors: run
yarn lint
and resolve all warnings and errors (if any). You might see warnings and errors like this:
warning 'temp' is assigned a value but never used @typescript-eslint/no-unused-vars
✖ 1 problem (0 errors, 1 warning)
- Add Commitlint config:
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
Conventional config is used here, you can also define your config with different rules.
- Install git hooks
yarn prepare / npm prepare
Note: Using Husky with Yarn 2 requires different steps.
- Add hooks: you can add any number of hooks you need. In this case, we are adding a pre-commit hook that will check the linting and run tests. We are also adding a Commitlint hook.
npx husky add .husky/pre-commit 'yarn lint && yarn test --watchAll=false'
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'
For more specific use cases for husky, you can check the recipes.
Et voila, this is all you needed to do.
You can test the hook by simply committing. git commit -m "foo: this will fail"
. You should see this in the terminal.
⧗ input: foo: this will fail
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg hook exited with code 1 (error)
Note: If you want to skip these hooks, you can commit directly with
-n/--no-verify
option likegit commit -m "yolo!" --no-verify
If you are starting with a new project, you can clone these repos with all the steps already done.
Top comments (0)