Format all the things

Photo Credit: Kevin Frayer

Format all the things

Prettier

Prettier is a brand new javascript library. Its simple goal is to reformat your code. For instance, when I write this:

and run prettier on it, I’ll ultimately get this:

You can try it for yourself at prettier’s website

Looks awesome doesn’t it? You don’t need to be a stylish developer anymore! But let’s be honest: not all developers are enthusiastic about this new tool. There are two kinds of developers, those who like when a program helps them to format their code, and those who don’t.

There are some benefits: using prettier you won’t waste your time reformatting your code because your destructuring expression overreaches your config’s character cap. You will no longer have conflicts because your colleagues changed indentation on the code you’re currently working on.

But it also comes with some tradeoffs. The first one is your coding style. We generally add line breaks between chained calls on an API (example here). Prettier will make this fit on one line if it can, and your code will lose some clarity. The same thing goes with the parentheses you add in complex boolean operations (example here). You will have to remember operator priorities.

For a relatively big project like ours, we prefer adding some consistency to our code in order to avoid wasting our time on solving conflicts, at the expense of losing a little bit of readability and style.

How to configure it?

We already have eslint setup in our project with some rule tweaks. So for us, Prettier had to interface smoothly with eslint. Fortunately it comes with a bunch of useful plugins.

  • eslint-config-prettier: this library disables all eslint rules that conflict with the Prettier formatting. Without it we would need to turn off those rules manually.
  • eslint-plugin-prettier: this library includes Prettier proper formatting as an eslint rule. So if our code is not well formatted, eslint will throw errors. This is the most important plugin for us, as it makes the linting fail if the code is not well formatted. Formatting is now mandatory!
  • prettier-eslint (prettier-eslint-cli): this plugin just runs prettier followed by eslint --fix command. The CLI version allows us to use it from the command line.

With these libraries, we can format all our code base and apply Prettier and eslint rules.

Migration

First we had to format the whole repository. This results in a pretty big PR, 670 modified files, +11700 -11113 changes… The implication is obvious: if you choose to use Prettier on your project, it had better be set up from the start.

Anyway, once this huge PR was merged, we had to rebase other PRs. You can see it coming: if your rewrite most of your code and rebase other changes on it, there is nearly no way you can avoid conflicts. But in reality it’s (almost) easier than it seems. Since all modifications were generated by Prettier, we can simply discard them and regenerate them after the rebase.

So, the first thing to do was to rebase on the parent of the format commit in order to resolve all conflicts that were not related to the formatting. To put it differently, we are sure that in next rebase conflicts will only be related to Prettier’s changes.

git rebase 0404b07~
# where 0404b07 is the git hash of the format commit parent

After that, we rebased our branch on the “prettier” commit, and we asked git to automatically keep the conflicting changes from the branch and to discard those from Prettier.

git rebase 0404b07 -s recursive -X theirs

Then we just needed to re-run Prettier to reformat the rebased code. After this, branches were well formatted and could get back to their normal life-cycle.

How does it work on daily basis?

First, adding the following scripts in the package.json file enables us to use prettier as a yarn (or npm) command.

The first line is used to format files provided as parameters and is used in a git pre-commit hook. The second line was there to format the whole codebase and should not be used anymore. This command takes around 1 minute to execute which is a little too long to be used in the development process. It’s more interesting to plug Prettier in our IDE and only format modified files.

Even though we now enforce a machine-generated code style, everyone is still free to use their favorite IDE with any formatting and syntax settings they like. Those using atom or sublime-text can use plugins for the save action (atom plugin here with “ESLint Integration” checkbox and sublime-text plugin here). Every saved file will be automatically formatted by Prettier. This is clearly the most comfortable solution.

Those used to applying the format action in Webstorm will have to configure an external tool to do it. Here is a good article to help you setup an external tool if you are interested in this solution.

Finally we wrote a pre-commit hook and added it to our documentation. It automatically runs prettier on all added files from our javascript sources. lint-stage does the same, but we don’t want to force the whole team to use it. It’s clearly not necessary to run it twice, for those who have a save action which already runs Prettier.

Here’s an example of our pre-commit hook:

git diff --name-only HEAD | grep -E "src/.*\.js.?$" | xargs yarn format

In conclusion

Prettier is a new tool to add to your chain. Its role is to format the code for you in a very strict way. Thanks to a bunch of plugins that complement it, it also plays nicely with and applies eslint rules. Like we said, there are few sacrifices to make in terms of clarity, but it allows you to stop taking care of things that add no real value to the code you write. It also helps you to reduce meaningless conflicts and debates on “how we should write this”. We plan to use it on all our javascript repositories, for greater consistency and good.


By the way, if you found a typo, please fork and edit this post. Thank you so much!