Beautifying Code with Prettier

Prettier[29] describes itself as “an opinionated code formatter.” First introduced in 2017, it’s already soared to two million downloads per week from the npm registry. Using Prettier for the first time feels like a breath of fresh air: No more worrying about insignificant stylistic details as you work. No more arguments with your team about what’s most readable. Just let the formatter take care of it.

Let’s add Prettier to our project. Since we’re using ESLint, we want the prettier-eslint command, which ensures that Prettier formats our code in a manner that’s consistent with our ESLint config. To get that command, install the prettier-eslint-cli package:

 $ ​​npm​​ ​​install​​ ​​--save-dev​​ ​​[email protected]
 + [email protected]

Try running prettier-eslint against our test suite:

 $ ​​npx​​ ​​prettier-eslint​​ ​​tests/palindromes.test.js
 const palindromes = require("../palindromes");
 
 describe("palindromes()", () => {
  it("correctly identifies one-word palindromes", () => {
  expect(palindromes("madam")).toEqual(["madam"]);
  expect(palindromes("racecar")).toEqual(["racecar"]);
  });
 });
 success formatting 1 file with prettier-eslint

Prettier read tests/palindromes.test.js and emitted a formatted version as its output. (It didn’t change the file itself.) If you typed the original code exactly as it was presented in the book, there’s only one change in the formatted version: the strings are double-quoted rather than single-quoted, per Prettier’s default configuration. Happily, if you don’t like Prettier’s double-quote absolutism, you have the power to change it.

Configuring Prettier

By itself, Prettier has only a handful of configuration options.[30] However, when using the prettier-eslint bridge, you can exercise finer-grained control over formatting by setting ESLint rules.

Let’s say that you want to prefer single-quotes over double-quotes, except in cases where using double-quotes would avoid escaping (e.g., ’Your right’ is preferable to "Your right", but "You’re right" is preferable to ’You’re right’). You can express this with the ESLint quotes rule[31] like so:

 // .eslintrc.js
 module.exports = {
  ...
  rules: {
  quotes: [​'error'​, ​'single'​, { avoidEscape: ​true​ }],
  },
 };

Save the updated ESLint config file and re-run the format script against our test suite:

 $ ​​npx​​ ​​prettier-eslint​​ ​​tests/palindromes.test.js
 ...
 const palindromes = require('../palindromes');
 
 describe('palindromes()', () => {
  it('correctly identifies one-word palindromes', () => {
  expect(palindromes('madam')).toEqual(['madam']);
  expect(palindromes('racecar')).toEqual(['racecar']);
  });
 });
 success formatting 1 file with prettier-eslint

Another common piece of code style configuration is how to handle trailing commas. By default, Prettier strips away all unnecessary trailing commas. You may have noticed that the code in this book uses commas at the end of lines when those lines are object or array entries. (For example, the .eslintrc.js above exhibits this pattern.) Many JS developers prefer this style, in part because it keeps version control diffs simpler. For example, changing

 arr = [
  1,
  2
 ];

to

 arr = [
  1,
  2,
  3
 ];

results in a diff that looks like this:

 arr = [
  1,
 - 2
 + 2,
 + 3
 ];

If the last array entry already had a trailing comma, then the diff would be more concise and reflective of the actual change:

 arr = [
  1,
  2,
 + 3,
 ];

You can override this behavior by setting ESLint’s comma-dangle rule[32] to always-multiline, giving us our final .eslintrc.js:

 module.exports = {
  extends: [​'eslint:recommended'​],
  parserOptions: {
  ecmaVersion: 6,
  },
  env: {
  node: ​true​,
  },
  rules: {
  quotes: [​'error'​, ​'single'​, { avoidEscape: ​true​ }],
 'comma-dangle'​: [​'error'​, ​'always-multiline'​],
  },
 };

Open the Source Control sidebar and commit:

 :wrench: Initial Prettier setup

Integrating Prettier with VS Code

As with ESLint, Prettier works best when integrated into your editor, allowing you to format your code with a single keystroke—or, if you prefer, without you even having to ask.

Open the Extensions sidebar (X) and search for Prettier. At the top of the list you should see an extension named “Prettier” by Esben Petersen.[33] Click the green “Install” button.

Prettier is what’s known as a “formatter extension.” When you run the “Format Document” command (F), VS Code checks the installed extensions to see if any of them wants to perform formatting on the given document. Open up, say, tests/palindromes.test.js, and run that command now.

Running the formatter changed the single-quotes to double-quotes! That’s because the Prettier extension automatically reads the Prettier configuration from your project, but it doesn’t automatically detect the ESLint bridge. For that, you will need to change a setting. Let’s open up User Settings and add this line:

 // User Settings
 {
 ...
 "prettier.eslintIntegration"​: ​true​,
 }

Now try formatting tests/palindromes.test.js again. The double-quotes should go back to single-quotes, as expected. Save the file and confirm that the results of running the format script match up with the results of running “Format Document” in the editor:

 $ ​​npx​​ ​​prettier-eslint​​ ​​tests/palindromes.test.js
 ...
 1 file was unchanged

As handy as the “Format Document” command is, we can do better. Open the project’s Workspace Settings and add one final customization, editor.formatOnSave:

 {
 "files.exclude"​: {
 "node_modules"​: ​true​,
 "package-lock.json"​: ​true
  },
 "[javascript]"​: {
 "editor.tabSize"​: 2
  },
 "editor.formatOnSave"​: ​true
 }

The editor.formatOnSave flag does just what it sounds like, running “Format Document” for you every time you save a file. Try it now: open up a few files in the project, make tweaks, hit save, and watch them instantly change. Achieving consistent formatting has never been easier!

If you’re feeling adventurous (or impatient), there’s an editor.formatOnType flag, too. Most developers find this mode too jarring, but if you have a taste for fast feedback, it’s worth trying out.

Adding Project Lint Scripts

You’ve learned how to run ESLint and Prettier from the command line with npx, and directly from your editor. But that knowledge is locked inside your head! To make your project more approachable to potential collaborators, it’s a good idea to include some linting scripts in package.json.

Here we have a lint script that tests all JS files for lints and formatting issues, and a format script that runs all JS files through Prettier and overwrites the originals:

 {
 "name"​: ​"test-driven-palindromes"​,
 "private"​: ​true​,
 "version"​: ​"1.0.0"​,
 "description"​: ​""​,
 "main"​: ​"index.js"​,
 "scripts"​: {
 "test"​: ​"jest"​,
»"lint"​: ​"eslint . && prettier-eslint --list-different **/*.js"​,
»"format"​: ​"prettier-eslint --write **/*.js"
  },
 "keywords"​: [],
 "author"​: ​""​,
 "license"​: ​"ISC"​,
 "devDependencies"​: {
 "eslint"​: ​"^5.10.0"​,
 "eslint-plugin-jest"​: ​"^22.1.2"​,
 "jest"​: ​"^23.6.0"​,
 "prettier-eslint-cli"​: ​"^4.7.1"
  }
 }

To run against every JS file in the project, ESLint only needs the . argument, indicating the project directory. Prettier is a little more demanding, requiring a glob. The --list-different flag tells Prettier to list the names of any files with formatting issues, rather than emitting their formatted contents.

If you run these scripts, you should see some nice, boring output, since your code is already pretty:

 $ ​​npm​​ ​​run​​ ​​format
 ...
 2 files were unchanged

Later on, in Chapter 6, Continuous Integration and Collaboration, you’ll learn to use these scripts to enforce your code style standards automatically.

That concludes our introduction to Prettier. We’ve seen how to add Prettier to a project, how the prettier-eslint bridge lets us use ESLint rules to modify Prettier’s output, and how editor integration makes formatting with Prettier an effortless process.

In the next section, you’ll meet this chapter’s final piece of tooling: Wallaby.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.151.141