Many teams are familiar with the situation such as arguing in pull requests about how to place brackets, indent, and how to format code. This results in a waste of a lot of time and energy. It can also lead to conflict situations. If we can automate something, we should automate it. What tools can we use for this? Two are enough:
Let's take a look at how to use them using an example with React app.
What is Lefthook?
As documentation says, lefthook is a “fast and powerful Git hooks manager for Node.js, Ruby or any other type of projects”. What does it mean? This means that you can set up some commands to be executed when you do, for example, git commit or git push.
In our example, we will set up autoformatting to run before the commit. Also, you can add, for instance, running tests before a commit. If some command fails (for example, tests failed), then the changes will not be committed.
What is Prettier?
It is an “opinionated” code formatter. It supports many languages.
Setup a test app
-
create a test application
npx create-react-app lefthook-prettier-example cd lefthook-prettier-example
-
install prettier
npm install --save-dev --save-exact prettier # or yarn: yarn add --dev --exact prettier # Then, create an empty config file to let editors and other tools know you are using Prettier: touch .prettierrc.js
-
open
.prettierrc.js
and specify the config object. You can see all the options here and specify the ones that suit you
module.exports = { singleQuote: true, jsxSingleQuote: true, arrowParens: 'always', printWidth: 120, tabWidth: 2, useTabs: false, semi: false, endOfLine: 'auto', };
you can optionally assign formatting when saving the file (https://prettier.io/docs/en/editors.html).
-
if you configured formatting on saving, then check that everything works. To do this, open the
src/App.js
file in the IDE, make some changes, and click Save.Instead of this:
import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;
we get the formatted code:
import logo from './logo.svg' import './App.css' function App() { return ( <div className='App'> <header className='App-header'> <img src={logo} className='App-logo' alt='logo' /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className='App-link' href='https://reactjs.org' target='_blank' rel='noopener noreferrer'> Learn React </a> </header> </div> ) } export default App
NOTE: If you specify other options in the config, the result may differ.
-
install lefthook
npm i @arkweid/lefthook --save-dev # or yarn: yarn add -D @arkweid/lefthook # NOTE: if you install it this way you should call it with npx or yarn for all listed examples below. (for example: lefthook install -> npx lefthook install) # You can also install lefthook as a global dependency npm install -g @arkweid/lefthook
-
create and configure hooks for lefthook
# Initialize lefthook with the following command (it creates lefthook.yml in the project root directory) npx lefthook install # Register your hook (You can choose any hook from https://git-scm.com/docs/githooks). In our example it pre-commit githook: lefthook add pre-commit
-
open the
lefthook.yml
config file and add the commands to be executed before the commit
pre-commit: parallel: true commands: prettier: glob: 'src/*.{js,ts,jsx,tsx}' run: npx prettier --write {staged_files} && git add {staged_files}
-
to check, turn off auto-formatting on saving. Next, make changes to
src/App.js
and do a git commit
git add -A git ci -m 'Add lefthook and prettier' RUNNING HOOKS GROUP: pre-commit EXECUTE > prettier src\App.js 50ms SUMMARY: (done in 0.75 seconds) ✔️ prettier [master 4576031] Add lefthook and prettier
Check that
src/App.js
is re-formatted.
Conclusion
In this article, we used lefthook for the pre-commit hook. But there are other alternative tools like pre-commit or husky. They all have similar capabilities, and if you understand one of them, you can deal with the rest.
You can download the final result here.
Cover photo by Sai Kiran Anagani on Unsplash.
Top comments (0)