Formatting and Linting for JS
Tags: opensource
Published: 2021-11-06 00:23:52

## Intro

This week in my open source development course, we learned all about Static Analysis Tooling. Although I've worked on several projects that used tools such as Prettier, ESLint and Husky, I have never actually gone through the process of setting up these tools for other developers to use in my own projects. I added these tools to my static site generator, [Jellybean](https://github.com/lyu4321/jellybean), and I'll be talking about the process in this post. 

## Prettier
I chose [Prettier](https://prettier.io/) as the code formatter for my project, as I have used it before and it's probably one of the most well known code formatters for JavaScript. Following their installation guide, I was able to get Prettier installed by running the following commands:

```shell
npm install --save-dev --save-exact prettier
echo {}> .prettierrc.json
```

The second line `echo {}> .prettierrc.json` caused an error, but thankfully, a few of my classmates also encountered this error and I learned that it was because Windows uses Unicode UTF-16LE encoding by default, but JSON files are encoded in UTF-8 by default. By running the command through Command Prompt, I was able to bypass this issue and successfully create the .prettierrc.json file. 

In my .prettierrc.json file, I added the following configurations. There are many other options available, which you can find in the [Prettier docs](https://prettier.io/docs/en/options.html). 

```json
{
    "trailingComma": "es5",
    "tabWidth": 4,
    "singleQuote": true
}
```

I added the following to the scripts in my package.json file:

```json
    "prettier": "prettier --write .",
    "prettier-check": "prettier --check .",
```

And ran Prettier using `npm run prettier`. This changed my code quite a bit. For example, Prettier added newlines in many places, semicolons where I had missed them before, and wrapped function arguments in parenthesis, among other changes.

## ESLint
Like Prettier, [ESLint](https://eslint.org/) is a very commonly used tool that I see often so I chose it as the Linter for my repository. 

Again, I followed the installation docs and was able to install it quite easily by running these commands:

```shell
npm install eslint --save-dev
npx eslint --init
```

When running the second command, you can specify details about your project through the command line such as what framework it uses, where it runs, etc. which is used to automatically generate a configurations file:

![ESLint Init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2tjpbqe86t4ptmopzn3.png)

(Note: For "Where does your code run?", it should actually be "Node" instead of "Browser" and I had to go fix this in the config file later.)

I also added the following to the scripts in the package.json file:

```json
    "eslint": "npx eslint .",
    "eslint-fix": "eslint --fix .",
```

After checking my code with ESLint, I got one error from this line:

```js
md = new markdownit();
```

ESLint showed the error ""'md' is not defined  no-undef" and once I added the keyword "let", such as:

```js
let md = new markdownit();
```

This problem was resolved. 😀

## Integrating With VSCode

First, I installed the Prettier and ESLint extensions in VSCode. After doing this, in the Command Palate, I searched for **Configure Recommended Extensions (Workplace Folder)**. This creates an extensions.json file in your .vscode folder and you can add the extensions to your project by right clicking on an extension once it has been installed and selecting **Add to Workspace Recommendations**, as shown below: 

![Add to Workspace Recommendations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kq3lujqtxjugb2jzj8b.png) 

In the end, I added these two recommendations to my extensions.json file:

```json
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"],
```

For settings, I created a settings.json file in the .vscode folder. 

![Settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p74jul5kfds1f62le2iw.png)

You can see a list of possible options in the dropdown menu when you start typing. These are the configurations I added to my settings.json file:

```json
{
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "eslint.lintTask.enable": true
}
```

## Husky

The last step was to add a pre-commit hook, which checks staged files before you commit. I decided to use [Husky](https://typicode.github.io/husky/#/) because I had heard of this tool before and it seemed like a popular choice as well.

I ran the following commands:

```shell
npm install husky --save-dev
npm set-script prepare "husky install"
npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
```

The first line installs Husky, the second line adds a script to the package.json file, and the last two lines add the pre-commit hook. 

In the .husky/pre-commit file, I added the following lines:

```
npm run prettier
npm run eslint
```

To run Prettier and ESLint before a commit is made. 

Last but not least, I documented all these changes in a [CONTRIBUTING.md](https://github.com/lyu4321/jellybean/blob/main/CONTRIBUTING.md) file so that anyone who works on the project in the future will understand what tools are used and how to work with them. 

## Conclusion

I'm so glad I had a chance to learn about Static Analysis Tooling. Although I have used some of these tools before in other projects, I didn't have experience configuring them or adding scripts to run them from the command line, so this was a really useful exercise.

I have worked on large-scale projects in the past where everyone was using their own way of formatting and it was a bit of a mess and sometimes very frustrating. By having a standard for formatting and checking the code, it simplifies the process of collaborating with others and I will definitely keep this process in mind when creating other projects in the future.