The JavaScript, Web, and Node community is blessed these days by having easy-to-use (and not so easy-to-use) tools at our fingertips, along with documentation for them written by dedicated members of the community.
This post is about setting up the simplest quick-and-easy pipeline with some well known tools like Prettier for code quality/readibility, and Husky for automatically enforcing those rules in our codebase.
In some later posts we'll add build steps, testing, and some technology-specific tools like React and TypeScript. However, today we're keeping it simple and clean with only Prettier and Husky.
Also, keep in mind that many existing tools and frameworks like Create React App, Gatsby, and so on, already provide some of the tooling mentioned here. However, we are starting from zero because our purpose is mostly to learn about the tools and understand why they are used.
Once we understand how easy it is to set up these code quality tools, that is one less hurdle to jump through when trying to use these in your own project.
But Sammy, Why?
"That which cannot be automated, cannot be enforced."
-Brian Holt, @holtbt
High quality, familiar, consistent code is easier to read and understand. Additionally, code similar to your own is easier for you to understand.
How do I start?
Ok, step #1 is simple: create a new npm project, create a JS file, and write the ugliest, nastiest, most unreadable (but working) code you've written. Ignore style rules, best practices, and ignore what mean people say on Twitter. Get that out of your system.
Now that you got an unholy mess in front of you, our first of the two tools comes into play:
Prettier
Because sometimes we can't be trusted.
We are using Prettier version 1.16.4
.
Prettier is a code formatter - this means that it will grab your code and apply its own consistent style rules on it. It has some flexibility, but generally developers use the default rules to keep style consistent across projects.
Prettier will turn this inconsistent one-liner mess:
export function funkyFilteredNames(names = [...defaultNames]) { return names.filter((name) => name.toLocaleLowerCase()[0] == "a").map(name => name.toLocaleUpperCase()); }
Into this readable snippet:
export function funkyFilteredNames(names = [...defaultNames]) {
return names
.filter(name => name.toLocaleLowerCase()[0] == "a")
.map(name => name.toLocaleUpperCase());
}
How it does it is up to you. You can use Prettier as a CLI tool or you can let your text editor of choice handle it. To keep it simple (and let you use whatever you want) we are going to use the Prettier CLI.
If you want to see how to install Prettier on your IDE, check out their docs on the matter.
First things first - install Prettier: npm i -D prettier
.
Now do me a favor: open the file where your messy code is, and open the command line on the same directory as your file. While looking at your code, enter the following command:
npx prettier *.js --write
And boom, no longer a mess!
Congratulations, you have code style rules in your codebase! To make this easier, we will make the above snippet an npm script, with a few changes to find all JavaScript files:
// package.json:
{
// ...
"scripts": {
// other scripts
"pretty": "prettier \"**/*.js\" --write"
}
}
Now you only have to run npm run pretty
from within your project to format all the js files in it!
Congratulations, you made it easy! β¨
You can also make Prettier check the code instead of formatting it, and erroring the console out when the code isn't formatted:
"pretty-check": "prettier \"**/*.js\" --list-different"
But what about reminding yourself to run the formatter? Are you completely sure that you will run the Prettier every time? That's where our second tool for today comes in: Husky!
Husky
Because we so easily forget
We are using Husky version 1.3.1
π Husky makes it easier for us to write Git Hooks - commands that run when we call specific Git actions. We will use it to make sure that Prettier checks the code when trying to commit to the repository.
The steps for husky are simple, starting with the configuration file, which defines our hooks!
Create a file called .huskyrc
in the root of your project, and write in the following text to define a hook that will run pretty-check before every commit:
{
"hooks": {
"pre-commit": "npm run pretty-check"
}
}
Then we install Husky: npm i -D husky
Note: it is important that you install Husky after defining the .huskyrc
file. If anything, you can always reinstall the package. Additionally, you should delete the .git/hooks folder if Husky is still not working, and then reinstall the package. You can read a bit more about it in this GitHub issue
Now go to one of your files and write some ugly code. No need to make a mess like last time, a single single quoted string would be enough!
Save and attempt to commit the file and you will see this at the end of the response:
Husky rejected the commit because Prettier checked the code, and found that the code does not follow Prettier standards!
If you want, you can change the pre-commit hook to format the code instead of just checking it by changing the content of `"pre-commit"
to execute pretty
instead of pretty-check
.
Congratulations, you made it automatic! β¨
These days, setting up your workspace with a formatter is not difficult, and it goes great lengths for readability of your code.
Prettier is one today's most used JavaScript formatter with almost 3.5 million downloads weekly, and the developers have done a great job at making it easy to use and understand.
Husky allows us to write git commit hooks without much overhead or effort. Combined with Prettier, it makes it really hard to commit code that is inconsistent with the Prettier style guide.
I have set up this small project for you to check out the steps I described in the article:
SammyIsra / JsEasyPipeline
Example of a JS project with pipeline and code quality tools π
JsEasyPipeline
Accompanying project to my articles on Dev.to about implementing a JS pipeline/workspace tools π
The repo will have examples on how to implement various tools like Prettier, Husky, ESLint, TravisCI, TypeScript, and similar tools in that style.
This project shows how to implement project tools for JavaScript projects. The articles where I explain the tools are here:
Check out the branch Part1.PrettierAndHusky
for the code specifically for this article.
β€οΈ Thank you all for reading! More parts of this series will come later. I hope to use ESLint, TravisCI, and my own personal tools in future articles.
Top comments (11)
This is an unfair jab and also unnecessarily condescending.
Husky provides many benefits over plain git hooks. One, being able to manage the hooks from your project.json. This makes them visible to anyone viewing the source. They are also source controlled.
There's nothing wrong with normal git hooks if you prefer to set them up the original way, or if you find it easier to do it that way. Husky just helps you make it a but easier to work with, and sets them up in a familiar way with a json file.
Have you ever tired to get a team of 10+ Devs to manually install and update git hooks?
Bloat ? who cares about a build tool being bloated, it dosnt ship to production. Also this tool literally literally solves the issue by blocking pushes until its correct.
If you have ever had to managed a project or maintain consistencies between the juniors you would know this is a life saver. But i guess your arrogant attitude never has got you into a position of having to manage others.
It doesn't mimic it
It's using git hooks in the background, automatically adding them when you run
npm install
Agree to disagree.
Please edit that sentence to say "tonight" instead, it's the least you can do given the circumstances :)
I'm not sure I understand, what circumstances?
Using the turn of phrase "simple and clean". As in "Simple and Clean", the meme song from Kingdom Hearts game. The name drop sentence in the lyrics contains the word "tonight" but not "today".
Oh! Sorry I don't play Kingdom Hearts. I feel I was too late for that train.
Me neither. Maybe someday!
There's also just been a new one after I imagine a decade. That's why I see it everywhere.