Prettier is a JavaScript code formatter that supports many newer language features such as ES2017, JSX, TypeScript, and others. It’s great because you end up with a much more consistent codebase and not have to worry about formatting. The author of that package wrote a very detailed blog post explaining all the benefits and I highly recommend you check it out!. You can also try it out in the prettier playground to get a feel for how it works.
Like other cli-tools, you have the option of installing it globally or locally - I prefer the latter as it gives me more control over version upgrades as well as a more consistent experience for all developers of the codebase.
$ yarn add --dev prettier
Prettier uses cosmoconfig for config file support which means it
supports using package.json
to store your configuration. This is the
prettier
section of the package.json file we currently use at
Switchboard:
"prettier": {
"trailingComma": "es5",
"bracketSpacing": false,
"singleQuote": true,
"printWidth": 120
}
Your repository structure will be unique and it is a good idea to make it easier for your developers to run prettier. In JavaScript projects, npm scripts are the ideal place for these kind of “makefile style” targets.
We use the following prettier
target for Switchboard (in package.json):
"scripts": {
// ...
"prettier": "prettier --write \"{frontend,backend,website/assets/js}/**/*.js\""
},
(Switchboard uses a monorepo structure which is the reason for that zany file glob!)
The script target allows a developer to run yarn run prettier
and not have to
worry about supplying & escaping globs on the command line.
Of course all this tooling is moot if developers don’t actually run prettier (hey sometimes we forget!). There are integrations available for common IDEs such as vim, emacs, and sublime.
There is also the option of running the prettier
command as a post-commit
hook locally. This has the downside of needing all your developers to add this
post-commit hook to their local checked-out repos, and unfortunately you still
don’t really have a way of verifying the final output.
I am personally a fan of option 3 - validating that prettier
was run by
the developer during the CI build. This takes a bit of the belt-and-suspenders
approach by allowing developers to choose whatever system works for them
locally, but validating the result centrally.
This is where the prettier-check
cli-tool comes in handy.
$ yarn add --dev prettier-check
This tool proxies all supplied arguments into prettier which makes it perfect for enforcing a consistent codebase!
Create a new target to validate that prettier was run by the developer in package.json.
"scripts": {
// ...
"prettier": "prettier --write \"{frontend,backend,website/assets/js}/**/*.js\"",
"prettier-check": "prettier-check \"{frontend,backend,website/assets/js}/**/*.js\""
},
On your CI system, yarn run prettier-check
will now fail your build if
prettier was not by the developer on the checked-in code!
This setup has an interesting side-effect of enforcing repository-specific prettier settings. I’ll demonstrate this with an example. Using the config we described above, suppose you ran the following command:
$ `npm bin`/prettier --no-config --write "{frontend,backend,website/assets/js}/**/*.js"
You would find that a subsequent invocation of yarn run prettier-check
will
fail your build even though prettier was run. The reason of course is that
prettier was not run with the repository-specific settings and is therefore
invalid.
The point I’m trying to demonstrate is that having a validation step on your CI system enforces a much more consistent codebase and keeps things simpler.