Stop arguing about code style in pull requests!
Tags: javascript, git, tooling
Published: 2022-04-13 10:37:06

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:

1. [lefthook](https://github.com/evilmartians/lefthook)
2. [prettier](https://prettier.io)

Let's take a look at how to use them using an example with React app.
<br />
## What is Lefthook?

As [documentation](https://github.com/evilmartians/lefthook) 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.
<br />
## What is Prettier?

It is an “opinionated” code formatter. It supports many languages. 
<br />
## Setup a test app


1. create a test application

    ```bash
    npx create-react-app lefthook-prettier-example 
    cd lefthook-prettier-example
    ```

2. install prettier

    ```bash
    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
    ```

3. open `.prettierrc.js` and specify the config object. You can see all the options [here](https://prettier.io/docs/en/options.html) and specify the ones that suit you

    ```javascript
    module.exports = {
      singleQuote: true,
      jsxSingleQuote: true,
      arrowParens: 'always',
      printWidth: 120,
      tabWidth: 2,
      useTabs: false,
      semi: false,
      endOfLine: 'auto',
    };
    ```

4. you can optionally assign formatting when saving the file (https://prettier.io/docs/en/editors.html).

5. 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:

    ```jsx
    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:

    ```jsx
    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.

6. install lefthook 

    ```bash
    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
    ```

7. create and configure hooks for lefthook

    ```bash
    # 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
    ```

8. open the `lefthook.yml` config file and add the commands to be executed before the commit

    ```yml
    pre-commit:
      parallel: true
      commands:
        prettier:
          glob: 'src/*.{js,ts,jsx,tsx}'
          run: npx prettier --write {staged_files} && git add {staged_files}
    ```

9. to check, turn off auto-formatting on saving. Next, make changes to `src/App.js` and do a git commit

    ```bash
    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
    ```

10. Check that `src/App.js` is re-formatted.

<br />
## Conclusion

In this article, we used lefthook for the pre-commit hook. But there are other alternative tools like [pre-commit](https://github.com/pre-commit/pre-commit) or [husky](https://github.com/typicode/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](https://github.com/pavelkomiagin/lefthook-prettier-example).

Cover photo by [Sai Kiran Anagani](https://unsplash.com/@anagani_saikiran) on [Unsplash](https://unsplash.com).