In this article, we’re going to learn how we can improve the quality of codes we commit to git by beautifying and linting at the point of commit. We’ll walk through an example React app to see how with husky, we can configure githooks to trigger code linting and beautification before committing to git.
When we write softwares, we always want to keep our codebase to be clean, readable, free from unused fragments and consistent across files. However, this is a hectic task to handle manually.
In this tutorial, I will be showing you how you can effortlessly make setups for automatic code linting and beautification before any commit to git.
Getting Started
Since we’ll be using React for this tutorial, the first step is to create a new react application.
I will be scaffolding a new React application with the CRA tool.
# scaffold new react application
npx create-react-app react-husky-setup
# navigate to the newly created application
cd react-husky-setup
Next, we will install all the tools we need as development dependencies.
I have outlined every dependency we need to install before we unlock this super powers I have been talking about.
[ ] Install PrettierJS
[ ] Install EsLint and EsLint plugins
[ ] Install Lint-staged
[ ] Intall HuskyJS
[ ] Unlock Awesomeness
Install PrettierJS
According to the official website,
Prettier is an opinionated code formatter with support for: JavaScript, including ES2017 , JSX, Angular, Vue, Flow, TypeScript; CSS, Less, and SCSS, HTML, JSON, GraphQL, Markdown, including GFM and MDX and YAML.
It removes all original styling* and ensures that all outputted code conforms to a consistent style..
We will be using prettier to format badly indented codes and perform code formatting before making commits. Let’s install prettier
# install with yarn
yarn add prettier --dev --exact
# install with npm
npm install --save-dev --save-exact prettier
We then create a .prettierrc
file in our root directory, this will allow us configure prettier based on our standards.
This is my preferred configuration:
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"proseWrap": "always",
"htmlWhitespaceSensitivity": "css",
"quoteProps": "as-needed"
}
Install ES Lint and ES Lint plugins
ESLint is a pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. ESLint helps you maintain your code quality with ease.
# install with yarn
yarn add eslint babel-eslint eslint-config-prettier eslint-plugin-html eslint-plugin-prettier --dev
# install with npm
npm install --save-dev eslint babel-eslint eslint-config-prettier eslint-plugin-html eslint-plugin-prettier
We are installing eslint along with some eslint based plugins. The extra plugins and their uses are listed in the table below:
babel-eslint |
This allows you to lint ALL valid Babel code including experimental features (such as new features). |
eslint-config-prettier |
This turns off all rules that are unnecessary or might conflict with Prettier. |
eslint-plugin-html |
This will allow eslint to lint inline scripts embeded within HTML |
eslint-plugin-prettier |
This runs Prettier as an ESLint rule and reports differences as individual ESLint issues. |
We also need to create an .eslintrc
file in our root directory to configure eslint. This is my preferred configurations:
{
"env": {
"browser": true,
"es6": true
},
"extends": ["eslint:recommended", "react-app", "prettier"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["react-hooks"],
"rules": {
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"no-console": 2,
"no-alert": 2,
"no-func-assign": 1,
"no-invalid-regexp": 1,
"no-unreachable": 1,
"default-case": 1,
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}
Install Lint-Staged
Lint staged allows us to lint only staged code, this is because running a lint process on a whole project is slow and some linting results from an overall linting can be irrelevant. Therefore, lint staged helps us to confine our linting to only staged codes making the process faster and efficient (since we only need to lint codes we intend to commit anyway).
# install with yarn
yarn add lint-staged --dev --exact
# install with npm
npm install --save-dev lint-staged
We’ll then setup lint-stage by including a config object in our package.json
file
#... Rest package.json
"lint-staged": {
"**/*.+(js|ts|graphql|yml|yaml|vue)": [
"eslint --fix",
"prettier --write",
"git add"
],
"*/*.+(css|sass|less|scss|json|html)": [
"prettier --write",
"git add"
]
}
Here we are configuring lint-staged to run `eslint, prettier` then perform a new `git add` to staged codes for all `js,ts,graphql,yaml,vue` files and to only run `prettier` and a `git add` for `css, sass, less, scss, json, html` files.
Install HuskyJS
When we use git, we automatically have access to use git hooks, git hooks allow us to hook into various hook events and perform functions before or after this events. We can see a list of available git hooks if we check .git/hooks
directory in our project.
You can see also see the list of supported hooks from the documentation. However, for this tutorial we are only really concerned about the pre-commit
hook. This hook is executed before a git commit operation.
The turn down of using git hooks is that you can only write them as bash scripts. But we dont want to go through the hazzle of learning a new language for this purpose, and that is where husky comes into play.
Husky allows us write git hooks easily and makes it easier to share them across team members.
# install with yarn
yarn add husky --dev
# install with npm
npm install --save-dev husky
To configure husky to use our custom pre-commit
hook, we need to include husky configuration to our package.json file
#... Rest package.json
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
This tells husky to run the commands we defined for lint-staged
in our package.json
file.
Unlock Awesomeness
Finally we’ve gone through all installations and setups, from my .eslintrc
rules, I enabled and error flag for console
statements in my codebase, so let’s try adding a console.log
statement to our App.js
file and try committing our code to git.
Aha! Eslint flags the console statement so our intended commit is reverted and we get to see what line has errors.
Top comments (1)
Nice illustration. Do we have to follow the same steps for every project we tend to build?