Automate JavaScript Code Linting and Formatting in 5 simple Steps
Tags: javascript, node, programming, codenewbie
Published: 2021-08-18 05:33:23

<!-- wp:heading -->
<h2><a href="https://dev.to/new#what-are-git-hooks"></a>What are Git Hooks?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Git hooks are basically scripts fired before an important action occurs, eg: before a commit is made, before code is pushed to a repo after a commit is made, etc. You can learn more about Git Hooks and the different kinds of hooks over <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">here</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A pre-commit hook is a hook that is run before you make a commit.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><a href="https://dev.to/new#tldr"></a>TLDR</h2>
<!-- /wp:heading -->

1. Install Mocha and Chai for testing
2. Install Eslint for Linting
3. Install Pretty and Pretty-quick for formatting
4. Install Husky to setup pre-commit hook
5. Test the pre-commit hook

<!-- wp:heading -->
<h2><a href="https://dev.to/new#current-project-setup"></a>Current Project Setup</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>I have two files, the first file is called 'utils.js'. It has 4 basic arithmetic functions.</p>
<!-- /wp:paragraph -->

```javascript
const add = 
(a, b) => a + b

const subtract = 
(a, b) => a - b

const multiply = 
(a, b) => a * b

const divide = 
(a, b) => a / b

module.exports = {
    add,subtract,multiply,divide
}
```

<!-- wp:paragraph -->
<p>As you can see it is weirdly formatted and is missing semi-colons. This is done intentionally.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The second file is <code>index.js</code>. It simply imports the functions from utils.js and exports them.</p>
<!-- /wp:paragraph -->

```javascript
const {add, 
    subtract, 
    divide, 
    multiply} = require('./utils')
module.exports =  {add,subtract, divide, multiply}
```

<!-- wp:paragraph -->
<p>This is also intentionally formatted in a weird manner.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The project also has a basic package.json file generated using&nbsp;<code>npm init</code></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><a href="https://dev.to/new#step-1-setup-testing"></a>Step 1 Setup Testing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will use mocha and chai for testing. We will write a single test case for each of our functions. To learn more about mocha and chai in-depth, refer to&nbsp;<a href="https://blog.logrocket.com/a-quick-and-complete-guide-to-mocha-testing-d0e0ea09f09d/">this article</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, let's install mocha and chai</p>
<!-- /wp:paragraph -->

```bash
npm install --save-dev mocha
```

<!-- wp:paragraph -->
<p>Next, let's install chai</p>
<!-- /wp:paragraph -->

```bash
npm install --save-dev chai
```

<!-- wp:paragraph -->
<p>Now, we will create a file 'tester.js', and add a few tests to it.</p>
<!-- /wp:paragraph -->

```javascript
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-undef */
const {
  add, subtract, divide, multiply,
} = require('.');
assert = require('chai').assert;

describe('Sum', () => {
  context('Adding 1 and 1', () => {
    it('should return 2', () => {
      assert(add(1, 1) === 2);
    });
  });
});

describe('Subtract', () => {
  context('Subtracting 1 from 1', () => {
    it('should return 0', () => {
      assert(subtract(1, 1) === 0);
    });
  });
});
```

<!-- wp:paragraph -->
<p>I have not included the entire tester file, there are a couple more test cases for multiply and divide.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Inside your package.json, add the following under scripts</p>
<!-- /wp:paragraph -->

```json
"test": "mocha --timeout 2000 tester.js"
```

<!-- wp:paragraph -->
<p>If you do not have 'scripts' in your package.json, create one. It should look like this</p>
<!-- /wp:paragraph -->


```json
"scripts": {
  "test": "mocha --timeout 2000 tester.js"
}
```

<!-- wp:paragraph -->
<p>Now you can go to the terminal and run the following command</p>
<!-- /wp:paragraph -->

```bash
npm test
```

<!-- wp:heading -->
<h2><a href="https://dev.to/new#step-2-setup-linter"></a>Step 2 Setup Linter</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will use the package <a href="https://www.npmjs.com/package/eslint">eslint</a>. First, let's install the package</p>
<!-- /wp:paragraph -->

```bash
npm install eslint --save-dev
```

<!-- wp:paragraph -->
<p>Now we will need to initialize our linter</p>
<!-- /wp:paragraph -->

```bash
./node_modules/.bin/eslint --init
```

<!-- wp:paragraph -->
<p>You will get a bunch of questions, answer them based on your project.<br>Finally, we will add a new command inside 'scripts' in 'package.json' You can add this under the 'test' command we added in the previous section.</p>
<!-- /wp:paragraph -->

```json
"lint": "eslint --fix *.js"
```
<!-- wp:paragraph -->
<p>This will run the linter on all your javascript files and fix the linting errors wherever it can.<br>You can also disable some es-lint checks by adding comments to the top of the file or above certain lines. For example, I disabled a couple of checks in the 'tester.js' file</p>
<!-- /wp:paragraph -->

```javascript
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-undef */
```

<!-- wp:heading -->
<h2><a href="https://dev.to/new#step-3-setup-prettier"></a>Step 3 Setup Prettier</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will have to install a couple of packages&nbsp;<a href="https://www.npmjs.com/package/prettier">prettier</a>&nbsp;and&nbsp;<a href="https://www.npmjs.com/package/pretty-quick">pretty-quick</a>&nbsp;to format the code.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Install prettier using the following command</p>
<!-- /wp:paragraph -->

```bash
 npm install prettier -save-dev
```

<!-- wp:paragraph -->
<p>Install pretty-quick using the following command</p>
<!-- /wp:paragraph -->

```bash
npm install pretty-quick --save-dev
```

<!-- wp:paragraph -->
<p>Now we will add another command to our 'scripts' section in 'package.json'</p>
<!-- /wp:paragraph -->

```json
  "pretty-quick": "pretty-quick"
```
<!-- wp:paragraph -->
<p>Do not run the command right now. Let's set up the pre-commit hook and run the command automatically.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><a href="https://dev.to/new#step-4-setup-husky"></a>Step 4 Setup Husky</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will use <a href="https://www.npmjs.com/package/husky">husky</a> to set up our pre-commit hook.<br>Install the package</p>
<!-- /wp:paragraph -->

```bash
npm install husky@4 --save-dev
```

<!-- wp:paragraph -->
<p>If you install V5 of husky, you might need to do some additional work to set up the pre-commit hook.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>After installation add the following inside your 'package.json'</p>
<!-- /wp:paragraph -->

```json
"husky": {
    "hooks": {
       "pre-commit": "pretty-quick --staged && npm run lint && npm test"
    }
  }
```
<!-- wp:paragraph -->
<p>Basically, we tell husky to run the above commands (pretty-quick, lint, and the tests) before our files can be committed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The&nbsp;<code>--staged</code>&nbsp;runs the formatter only on the staged files.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><a href="https://dev.to/new#step-5-test-precommit-hook"></a>Step 5 Test Pre-commit hook</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now we can finally test our pre-commit hook.<br>First, add your files</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="bash" class="language-bash">git add .</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Type the following command to commit your files</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="bash" class="language-bash">git commit -m "Test commit"</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You should see husky running the prettier, linter and testing scripts. Below is a screenshot of the terminal.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"linkDestination":"custom"} -->
<figure class="wp-block-image"><a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TIZwZd3t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3u3n8zlk687rf06gv0do.png"><img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TIZwZd3t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3u3n8zlk687rf06gv0do.png" alt="Screen Shot 2021-08-18 at 12.59.18 AM"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>If the linter returns an error or one of the test cases fails, the commit will be unsuccessful and your files will remain in the staging area and not be committed.</p>
<!-- /wp:paragraph -->