Keep your code clean forever

By formatting all of your .html, .css and .js files automatically every time you save or commit them

… because formatting your code manually in 2018 is already passé. You could still do it, but why? ;) Machine will be quicker and better at it.

Being more specific, by having your files formatted automatically by your IDE or CLI tools, you’re gaining significant advantages:

  • Your codebase is written in one consistent style, no matter how many developers collaborate on it.
  • Half of your code style guide isn’t needed anymore. Why teach yourselves about tabs or spaces, when it will be reformatted automatically anyways? Leave the code style to robots. Focus on the code instead.
  • You will write your code faster. Remember those times when you had to ENTER a new line every time you wanted to call an another method? Or you had to wonder for 10 seconds about whether to keep your array in one line or multi lines? Forget about it now. The IDE will do it for you. The fewer keystrokes you have to use to write your code, the more of it you’ll be able to write.
  • You can focus on the code, not the style, in your code reviews. Skip having rarely effective and totally-not-fun discussions like “I think we ought to use additional parentheses here. This is a bit too unreadable now.”. Enjoy having more time and energy, and when reviewing PRs, focus what is most essential in them: their introduced code and its’ logic.
  • All in all, it will improve your codebase and help you avoid bugs. Because even if it just means tidying up your spaces, it also means this: your code will be much clearer, and you’ll have more time to focus on your code, not anything else.

In addition, setting up all of it for your whole codebase will take you just about 5 to 15 minutes. Why not give it a try?


How to do it?

Basically:

  1. choose your formatter (f.e. Prettier) and setup a common config for it,

2. configure your IDE, so it formats your code automatically every time you save a file,

3. (optionally) format your existing codebase by running one CLI command,

4. (optionally) setup git precommit hooks, so it will be impossible to push badly formatted code,

5. (optionally) setup CI hooks, so it will fail if somebody manages to push badly formatted code.

And that’s it! If you complete in all of the steps above, your code will be clean and readable forever.

To help you with each of the steps, I’ve decided to break down each of them and describe it, on our own example, where we managed to setup Prettier and HTML Beautifier for all of our files, together with git and CI hooks.

Step 1.: Choose your formatters

Many of the current IDEs already have auto formatting built in (VSCode, Atom, WebStorm). The problem is, very often each one of them has its’ own implementation and configuration of the formatter. Unless you’re the only developer in your company, or you all are working with the same IDE configurations, you’ll want to standardise it.

When it comes to frontend web development, most of the folks are using Prettier now. It is stable since long and has solid support for language syntaxes like JS, JSX, TypeScript, JSON, CSS, LESS, SCSS, GraphQL (with more languages like SQL, Java, PHP, Python, Ruby on its’ way).

Prettier also does support HTML, but right now its’ support is quite experimental. If you’re using frameworks like Vue or Angular, you might want to switch to something else for it. Luckily there’s js-beautify, which is handling those alternate HTML syntaxes without troubles. (It can also format JS and CSS as well, but I prefer Prettier’s way of doing that, IMO it’s a bit better at those syntaxes.)

Because of those reasons, we‘ve decided to go with both of them. We’re using prettier for all of our .js, .ts, .css and .less files, and js-beautify for Angular’s .html files.

Step 2.: Configure the formatters

A lot of folks might just go with the default settings, if they don’t care about the code style that much.

For us, that wasn’t the case though. We already had our own code style. We didn’t want to change it, as many devs got used to it already. We really wanted that introducing the automatic code formatters wouldn’t change our existing style of writing code. Luckily, it wasn’t a problem — both prettier and js-beautify can be easily setup by having a simple .prettierrc or .jsbeautifyrc in your project’s directory.

For example, here’s what we’re using:

# ./.jsbeautifyrc
{
"html": {
"brace_style": "collapse",
"indent_char": " ",
"indent_scripts": "normal",
"indent_size": 2,
"wrap_indent": 8,
"wrap_line_length": 80,
"max_preserve_newlines": 1,
"preserve_newlines": true,
"unformatted": ["a", "sub", "sup", "b", "i", "u"]
}
}
# ./.prettierrc
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "avoid"
}
# ./.prettierignore
dist
vendor
utils/scaffolds

Step 3.: Setup a command, to reformat your whole codebase at once

First, we wanted to format our whole existing codebase. By being honest, it wasn’t well formatted in most of the cases.

Formatting it by CLI should be as simple as running npm run format. It might be useful to have this one command that lets you format all of your files at once, f.e. after you copy or mass-edit a lot of files at once. (Though later on we’ll setup some CI & git precommit hooks, so luckily we’ll never have to do it anyways.)

Configuration may vary a bit in your project, depending on how you have your paths setup, but this is how we’ve done it in our repo:

npm install --save-dev prettier js-beautify
# ./bin/glob-ls.js
// A small helper that will list all files using `glob` lib
// Usage: `node bin/glob-ls.js 'src/**/*.js'`
const glob = require('glob');
const patterns = process.argv.slice(2);
patterns.forEach(pattern => {
glob(pattern, {}, function(err, files) {
if (err) throw err;
process.stdout.write(files.join('\n') + '\n');
});
});
# ./package.json
{
"scripts": {
"format": "npm run format:prettier && npm run format:html",
"format:prettier": "node_modules/.bin/prettier --config .prettierrc \"src/**/*.{ts,css,less,js}\" --write",
"format:html": "node bin/glob-ls.js 'src/**/*.html' 'build/**/*.html.ejs' | xargs node_modules/.bin/html-beautify -r"
}
}

Voila. Now, tidying up our code is just a matter of npm run format && git add . && git commit -m 'Reformat all the files' . ;)

Step 4.: Setup your IDE, so it formats your files automatically

Now we have our code clean. But we don’t want it to become ugly again, right?

Let’s configure our code editor so it formats our file every time we save it, automatically. Thanks to it, we won’t have to bother with running any kind of CLI commands.

The way how you have to set it up, will be dependant on your IDE, but in most of the cases, it’s enough to just install a plugin. Prettier has it for most of the currently used editors.

It might get more complicated when you’re using multiple formatters in one project though. For example, because prettier and js-beautify can format the same files, I assure you, they will interfere with each other. But it’s not a big problem to make them work together.

For example, we’ve setup our IDEs, so that prettier formats only the js and css files, and js-beautify only the html files; all of them doing it automatically after save. We’ve done it for all VS Code, Atom, WebStorm and VIM. See this gist if you want to see exact instructions how to do it.

Step 5.: Add a CI hook, to test if the code is well formatted

OK, we’ve got out code formatters, and seems like we’ve set it up in our IDE as well, but what if someone is evil and by some chance, somehow commits badly formatted code? Accidents happen, sometimes code can get messed during the git merges or a new developer might have failed to setup his IDE properly.

Let it happen too often while not doing anything about it, and you’ll end with your code base formatted badly again.

Thus, we added npm run format:test command to our CI flow, that checks our code whenever anything new is commited into the git repository. Thanks to it, even if someone commits bad code to our repo, his build will eventually become red in CI, forcing him (or someone else) to fix the code format sooner or later.

# ./package.json
{
"scripts": {
"format-test": "npm run format-test:prettier && npm run format-test:html",
"format-test:prettier": "node_modules/.bin/prettier --config .prettierrc \"src/**/*.{ts,css,less,js}\" -l"
"format-test:html": "node bin/glob-ls.js 'src/**/*.html' 'build/**/*.html.ejs' | xargs node bin/html-beautify-check.js",
}
}
# ./bin/html-beautify-check.js
# a custom script, that formats the file(s) with html-beautify,
# but instead of changing it, it only errors with 0/1 if it needs to be changed
APPDIR=$(realpath $(dirname $(dirname $0)))
TMPDIR=$(mktemp -d)
cd $APPDIR
for line in $*; do
filepath=$(realpath $line)
file=${filepath/$APPDIR\//}
mkdir -p $TMPDIR/$(dirname $file)
cp $APPDIR/$file $TMPDIR/$file
done
message=$(find $TMPDIR -type f | xargs node_modules/.bin/html-beautify -r | grep -v unchanged || true)
if [[ $message ]]; then
echo "$message" | sed "s#$TMPDIR##g" | sed "s#\.\.\/##g"
rm -rf $TMPDIR
exit 1
fi
rm -rf $TMPDIR

Step 6.: Add a git precommit hook, to test if the code is well formatted

Last, but not the least improvement. You’d might say: “So you’ll reject my super-duper-important PR, just because it has 1 space too much, even though the code works perfectly? Are you insane?”.

Well, I have already mentioned the reasons why the proper code formatting is important for me. But I also do hate CI that fails too often out of stupid reasons that could be easily avoided.

So, let’s add a git precommit hook, that will check your code formatting every time you’re trying to commit anything. It will run totally in the background, whenever you do git commit, git rebase, git merge or any other actions, that result in adding/modifying a commit.

Luckily, somebody else already had done the hard work for us. Husky is a cool npm lib that lets easily add a command into any of the git commit hooks. Lint-staged is a cool-as-well npm lib that lets you run a command only on the files that are currently locally staged in the git.

Configuration:

npm install --save-dev lint-staged husky@next
# ./package.json
{
"husky": {
"hooks": {
"pre-commit": "node_modules/.bin/lint-staged"
}
},
"lint-staged": {
"src/**/*.html": [
"bin/html-beautify-check"
],
"build/templates/**/*.html.ejs": [
"bin/html-beautify-check"
],
"src/**/*.{ts,css,less,js}": [
"prettier --config .prettierrc -l"
]
}
}

Now, whenever I’m commiting anything, I’ll see something like that in my console:

Cool, isn’t it?


TL;DR:

  • Format your code. Use robots for it, not humans.
  • It only takes a few minutes to set it up to be done automatically.
  • Remember about setting up CI and git precommit hooks as well, to make sure the code stays properly formatted forever.

P.S. Recruitee’s hiring! If you’re looking for a job in Elixir/TypeScript background, preferably in Poznań, Poland, check out our career opportunities. We might be a perfect match for you.

Like what you read? Give Jack Tomaszewski a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.