prettier/website/blog/2018-07-29-1.14.0.md

1046 lines
26 KiB
Markdown
Raw Normal View History

2018-07-29 10:25:22 +03:00
---
author: Ika (@ikatyang)
authorURL: https://github.com/ikatyang
title: "Prettier 1.14: YAML Support"
---
This release adds YAML support, pragma (i.e. `/** @prettier */`) support for every language, and improves performance on large files. It also adds support for several new syntax features, and has a few formatting tweaks to make your code even prettier. ✨
<!--truncate-->
## Highlights
### YAML
#### Support YAML ([#4563], [#4742], [#4773], [#4854] by [@ikatyang])
Prettier can now format YAML files! 🎉
The implementation is highly compliant with the [YAML spec](http://yaml.org/spec/), and backed by the excellent [`yaml`](https://github.com/eemeli/yaml) package thanks to [@eemeli]. A few highlights:
##### Word wrap
Just like in Markdown, well hard-wrap prose at 80-characters if it doesnt affect the meaning of the file.
Input:
<!-- prettier-ignore -->
```yaml
>
Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that its my very good honour to meet you and you may call me V.
```
Output: (`--prose-wrap always`)
<!-- prettier-ignore -->
```yaml
>
Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim
and villain by the vicissitudes of Fate. This visage, no mere veneer of
vanity, is a vestige of the vox populi, now vacant, vanished. However, this
valourous visitation of a bygone vexation stands vivified and has vowed to
vanquish these venal and virulent vermin vanguarding vice and vouchsafing the
violently vicious and voracious violation of volition! The only verdict is
vengeance; a vendetta held as a votive, not in vain, for the value and
veracity of such shall one day vindicate the vigilant and the virtuous.
Verily, this vichyssoise of verbiage veers most verbose, so let me simply add
that its my very good honour to meet you and you may call me V.
```
> Note: the [`proseWrap`](https://prettier.io/docs/en/options.html#prose-wrap) option is set to `preserve` by default so youll have to specify `always` or `never` to enable this feature.
##### Ignore a portion of the file
If for some reason you dont want to format a part of the YAML file, you can always put an ignore comment before it:
<!-- prettier-ignore -->
```yaml
# prettier-ignore
key : value
hello: world
```
### Front Matter
#### Format YAML front matter ([#4773] by [@ikatyang])
Prettier can now format `---`-delimited YAML front matter in CSS and Markdown files:
Input & Output (Prettier 1.13):
<!-- prettier-ignore -->
```markdown
---
key : value
---
# heading
content
```
Output (Prettier 1.14):
<!-- prettier-ignore -->
```markdown
---
key: value
---
# heading
content
```
### Pragma
#### Support `requirePragma`/`insertPragma` in every language ([#4688], [#4699], [#4713] by [@ikatyang])
Prettier 1.7.0 and 1.8.0 introduced two new options:
[`--require-pragma`](https://prettier.io/docs/en/options.html#require-pragma) and
[`--insert-pragma`](https://prettier.io/docs/en/options.html#insert-pragma).
However, these options were only supported in a few languages.
Now these options are available in every language, including YAML!
- YAML
<!-- prettier-ignore -->
```yaml
# @prettier
key: value
```
- CSS/Less/SCSS
<!-- prettier-ignore -->
```css
/** @prettier */
.class {
display: none;
}
```
- GraphQL
<!-- prettier-ignore -->
```gql
# @prettier
query Browse($offset: Int) {
browse(offset: $offset)
}
```
- Vue
<!-- prettier-ignore -->
```html
<!-- @prettier -->
<template>
<div>Template</div>
</template>
```
### JavaScript
#### Never inline decorators unless theyre lone parameter decorators ([#4830] by [@suchipi])
Previously, decorators were always inlined since MobX inlined them by convention,
but reports from the community led us to discover that MobX is the only major library that follows this convention.
Prettier now puts decorators on their own lines unless theyre parameter decorators.
<!-- prettier-ignore -->
```ts
// Input
@observer
class OrderLine {
@observable
price: number = 0;
@observable amount: number = 1;
foo(@required name) {
console.log(name);
}
}
// Output (Prettier 1.13)
@observer
class OrderLine {
@observable price: number = 0;
@observable amount: number = 1;
foo(@required name) {
console.log(name);
}
}
// Output (Prettier 1.14)
@observer
class OrderLine {
@observable
price: number = 0;
@observable
amount: number = 1;
foo(@required name) {
console.log(name);
}
}
```
#### Handle JSX whitespace separately from fbt whitespace ([#4717] by [@karl])
Previously, JSX whitespace was always preserved
since Facebook has a custom translation pipeline (`fbt`) that uses JSX syntax but treats whitespace differently than regular JSX,
which meant we couldnt change JSX whitespace without breaking the Facebook codebase.
In Prettier 1.14, we now detect Facebook `fbt` tags and handle whitespace for them differently from other JSX tags,
improving the consistency across different but equivalent inputs.
<!-- prettier-ignore -->
```jsx
// Input and Output from Prettier 1.13
first = (
<div>
Text<br />
More text<br />
And more<br />
</div>
);
second = (
<div>
Text<br />More text<br />And more<br />
</div>
);
third = (
<div>
Text
<br />
More text
<br />
And more
<br />
</div>
);
// Output from Prettier 1.14
first = (
<div>
Text
<br />
More text
<br />
And more
<br />
</div>
);
second = (
<div>
Text
<br />
More text
<br />
And more
<br />
</div>
);
third = (
<div>
Text
<br />
More text
<br />
And more
<br />
</div>
);
```
When the text separating tags or expressions is just a single character
we print the entire group on a single line where possible.
<!-- prettier-ignore -->
```jsx
// Input and Output from Prettier 1.13
x = (
<div>
{hour}:{minute}:{second}
</div>
);
x = (
<div>
{hour}
:
{minute}
:
{second}
</div>
);
x = (
<div>
{hour}:
{minute}:
{second}
</div>
);
// Output from Prettier 1.14
x = (
<div>
{hour}:{minute}:{second}
</div>
);
x = (
<div>
{hour}:{minute}:{second}
</div>
);
x = (
<div>
{hour}:{minute}:{second}
</div>
);
```
It also improves the output of edges cases like this:
<!-- prettier-ignore -->
```jsx
// Input
this_really_should_split_across_lines =
<div>
before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
</div>
// Output (Prettier 1.13)
this_really_should_split_across_lines = (
<div>
before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{
stuff
}after
</div>
);
// Output (Prettier 1.14)
this_really_should_split_across_lines = (
<div>
before
{stuff}
after
{stuff}
after
{stuff}
after
{stuff}
after
{stuff}
after
{stuff}
after
{stuff}
after
</div>
);
```
#### Break JSX in arrow functions in JSX expressions ([#4601] by [@duailibe])
In previous versions, JSX in arrow functions in JSX expressions followed the general fit-or-break rule,
but its less readable when iterating over an array.
Prettier 1.14 forces these arrow functions to break, improving readability.
<!-- prettier-ignore -->
```jsx
// Input
const UsersList = ({ users }) => (
<section>
<h2>Users list</h2>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</section>
)
// Output (Prettier 1.13)
const UsersList = ({ users }) => (
<section>
<h2>Users list</h2>
<ul>{users.map(user => <li key={user.id}>{user.name}</li>)}</ul>
</section>
);
// Output (Prettier 1.14)
const UsersList = ({ users }) => (
<section>
<h2>Users list</h2>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</section>
);
```
### TypeScript
#### Support for TypeScript 3.0 ([#4625], [#4757] by [@ikatyang])
A few new features that include new syntax are added in the upcoming TypeScript 3.0:
the [`unknown` type](https://github.com/Microsoft/TypeScript/pull/24439) and
[tuples in rest parameters and spread expressions](https://github.com/Microsoft/TypeScript/pull/24897).
Prettier 1.14 adds support for them so you can format them when TypeScript 3.0 is released.
<!-- prettier-ignore -->
```ts
// UnknownType
const json: unknown = JSON.parse(jsonText);
// RestType
type Foo = [string, number];
type Bar = [boolean, ...Foo];
// OptionalType
type Baz = [string, number?];
```
### JSON
#### Do not put values on a separate line from the key ([#4852] by [@ikatyang])
Putting long values on new rows is the core feature of Prettier,
but we found that it doesnt improve readability for objects with long string values inside JSON files.
Prettier 1.14 will not move an objects string value regardless if it fits the print width or not.
<!-- prettier-ignore -->
```json5
// Input
{
"description": "a long long long long long long long long long long long long long long long long long paragraph"
}
// Output (Prettier 1.13)
{
"description":
"a long long long long long long long long long long long long long long long long long paragraph"
}
// Output (Prettier 1.14)
{
"description": "a long long long long long long long long long long long long long long long long long paragraph"
}
```
### Markdown
#### Only align lists if theyre already aligned ([#4893] by [@ikatyang])
Previously, we always align lists for [better indenting experience and
as a workaround for indented codeblock mis-parsing](https://prettier.io/blog/2018/02/26/1.11.0.html#respect-tabwidth-for-list-items-3990-by-ikatyang),
but this introduced double spaces in front of ordered lists, which is not common in markdown.
In Prettier 1.14, we only align lists in the following cases:
- Theyre already aligned.
- Therere at least two spaces in front of the first list item.
- Theres an indented codeblock inside of it.
Input:
<!-- prettier-ignore -->
```md
1. 123
1. 123
---
1. 123
1. 123
---
11. 123
1. 123
---
11. 123
1. 123
---
1. 123
1. 123
```
Output: (Prettier 1.13)
<!-- prettier-ignore -->
```md
1. 123
1. 123
---
1. 123
1. 123
---
11. 123
1. 123
---
11. 123
1. 123
---
1. 123
1. 123
```
Output: (Prettier 1.14)
<!-- prettier-ignore -->
```md
1. 123
1. 123
---
1. 123
1. 123
---
11. 123
1. 123
---
11. 123
1. 123
---
1. 123
1. 123
```
### Performance
#### Performance improvement on big files ([#4790], [#4848] by [@sompylasar])
The core feature of Prettier is to wrap lines when they go past the print width,
and to do this we need to calculate the visual width of every character.
The easiest way to count them is by using JavaScripts `String#length` property
but some non-ASCII characters like CJK characters have widths larger than a Latin character.
2018-07-29 10:25:22 +03:00
As a workaround, we replaced those 2-char-wide characters with 2 spaces before calculating the strings length.
This works fine but it also slows down Prettier because we have to run the replacement on every token.
In Prettier 1.14, we check if the string contains only ASCII characters
so we dont need to perform unnecessary string replacement.
This results in a **20% speed-up** on large files.
## Other changes
### API/CLI
#### Support relative paths for `plugins` and `pluginSearchDirs` in config files ([#4667] by [@ikatyang])
In Prettier 1.13, we introduced a new `pluginSearchDirs` option that changes where Prettier looks for plugins.
It worked well when specified in the CLI since it was always relative to the current directory,
but relative paths didnt work in config files.
In Prettier 1.14, relative paths for `pluginSearchDirs` and `plugins` in config files are now supported.
#### Do not throw error if `prettier` installed in a directory not named `prettier` ([#4706] by [@asottile])
We added support for globally installed plugins in Prettier 1.13 by searching up the directory tree to
find the nearest `node_modules` from `prettier`. We assumed that there would always be a `prettier` directory
which caused Prettier to crash if it was in a differently-named directory.
We changed our searching logic in Prettier 1.14 so you should now be able to rename the `prettier` directory if you need to
(for example if publishing a fork to npm).
#### Support `filepath` in browser ([#4721] by [@ikatyang])
In Prettier 1.13, we added first-class support for running Prettier in the browser, but the only way to
choose which parser to use was via the `parser` option. Prettier 1.14 adds support for the `filepath` option in the browser
API, which will allow Prettier to infer which parser to use, just like the it can with the Node.js API. This
should be especially useful for web editor applications!
#### Expose `isPreviousLineEmpty` to plugins ([#4748] by [@warrenseine])
Previously, we exposed `isNextLineEmpty` to plugins but not `isPreviousLineEmpty`.
Prettier 1.14 exposes it, because it can be useful for some scenarios like directives in C#.
### JavaScript
#### Support BigInt literals ([#4697] by [@ikatyang])
[BigInt](https://github.com/tc39/proposal-bigint) literals are now supported in the default `babylon` parser.
<!-- prettier-ignore -->
```js
const bigInt = 1n;
```
#### Support `throw` expressions ([#4695] by [@VojtechStep])
[Throw expressions](https://github.com/tc39/proposal-throw-expressions) are now supported in the default `babylon` parser.
<!-- prettier-ignore -->
```js
const assert = x => x || throw new Error('...');
```
#### Always expand the first argument if the second argument is also a call expression ([#4657] by [@duailibe])
Previously, we had a special case to not break function calls
if there were only 2 parameters passed and the first parameter was a function.
This worked well, but if the second parameter was also a function, it didnt look very good.
<!-- prettier-ignore -->
```js
// Input
somePromise.then((args) => {
this.props.receiveFavoritesActions(id, [].concat(...args));
}, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`));
// Output (Prettier 1.13)
somePromise.then(args => {
this.props.receiveFavoritesActions(id, [].concat(...args));
}, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`));
// Output (Prettier 1.14)
somePromise.then(
args => {
this.props.receiveFavoritesActions(id, [].concat(...args));
},
({ isCanceled }) =>
!isCanceled && logger.warn(`Error getting actions for the product: ${id}`)
);
```
#### Add parens for await in bind ([#4778] by [@ikatyang])
Previously, Prettier wrongly removed the necessary parentheses for `await` in the experimental bind syntax,
causing its meaning to be change. Prettier 1.14 now preserves the parentheses correctly.
<!-- prettier-ignore -->
```js
// Input
const doBothThings = async () => {
const request = doAsyncThing();
return (await request)::doSyncThing();
};
// Output (Prettier 1.13)
const doBothThings = async () => {
const request = doAsyncThing();
return await request::doSyncThing(); // means `await (request::doSyncThing)`
};
// Output (Prettier 1.14)
const doBothThings = async () => {
const request = doAsyncThing();
return (await request)::doSyncThing();
};
```
#### Allow top level `super` and `await` ([#4823] by [@ikatyang])
`super` and `await` are not allowed to be in places other than classes and async functions, respectively,
but our [range format](https://prettier.io/docs/en/options.html#range) option didnt quite work properly when selecting the contents of a function.
Prettier 1.14 allows them to be everywhere.
<!-- prettier-ignore -->
```js
super();
await doSomething();
```
#### Blacklist `this` and `super` in functional composition heuristics ([#4836] by [@princed])
In Prettier 1.13, we improved the formatting for functional composition functions (e.g., `pipe`, `compose`, etc.)
by putting their parameters on their own line, but this introduced false positives for functions with the same name in classes.
Prettier 1.14 blacklists `this` and `super` in functional composition heuristics.
<!-- prettier-ignore -->
```js
// Input
class X {
x() {
this.compose(a(), b);
super.compose(a(), b);
}
}
// Output (Prettier 1.13)
class X {
x() {
this.compose(
a(),
b
);
super.compose(
a(),
b
);
}
}
// Output (Prettier 1.14)
class X {
x() {
this.compose(a(), b);
super.compose(a(), b);
}
}
```
### TypeScript
#### Support `import.meta` ([#4762] by [@ikatyang])
In Prettier 1.13, the version of the TypeScript parser we used did not support parsing `import.meta` syntax.
We updated our TypeScript parser in Prettier 1.14 so they are now parsed and formatted correctly.
<!-- prettier-ignore -->
```js
console.log(import.meta.url);
```
#### Optional property with StringLiteral key in class ([#4762] by [@ikatyang])
In the prior version, the `?` in an optional property with a string literal as the key was wrongly removed.
We fixed this bug in Prettier 1.14 so it wont be removed.
<!-- prettier-ignore -->
```ts
// Input
export class ClassExample {
"a-prop"?: boolean;
}
// Output (Prettier 1.13)
export class ClassExample {
"a-prop": boolean;
}
// Output (Prettier 1.14)
export class ClassExample {
"a-prop"?: boolean;
}
```
#### Throw error on multiple super classes in class ([#4762] by [@ikatyang])
Classes are only allowed to have one parent class
but the TypeScript AST allows for multiple since the `extends` clause
has the same structure internally as the `implements` clause.
Previously, any extra super classes were silently dropped during printing,
which may have caused confusion after formatting.
In Prettier 1.14, they are now marked as syntax errors instead.
<!-- prettier-ignore -->
```ts
// Input
class Foo extends BarComponent, BazService, QuuxProvider {}
// Output (Prettier 1.13)
class Foo extends BarComponent {}
// Output (Prettier 1.14)
/*
SyntaxError: Classes can only extend a single class.
*/
```
#### Support JSX spread child ([#4885] by [@ikatyang])
Previously, the `...` in children spread in JSX expressions were wrongly removed.
We fixed this issue in Prettier 1.14.
<!-- prettier-ignore -->
```tsx
// Input
const x = <div>{...[0]}</div>
// Output (Prettier 1.13)
const x = <div>{[0]}</div>;
// Output (Prettier 1.14)
const x = <div>{...[0]}</div>;
```
### Flow
#### Support `.js.flow` extension ([#4777] by [@ikatyang])
[`.js.flow`](https://flow.org/en/docs/libdefs/creation/#toc-declaring-a-module)
is the extension for Flow declaration files but previously we didnt recognize it.
In Prettier 1.14, they should be picked up automatically
so you dont need to add overrides for them in config files.
### CSS/Less/SCSS
#### Handle newline between front-matter and comment correctly ([#4701] by [@evilebottnawi])
Multiple newlines between front matter and a CSS comment were replaced with a space in Prettier 1.13.
In Prettier 1.14, we print a newline between them instead.
<!-- prettier-ignore -->
```css
/* Input */
---
key: value
---
/* comment */
.class {
display: none;
}
/* Output (Prettier 1.13) */
---
key: value
---
/* comment */
.class {
display: none;
}
/* Output (Prettier 1.14) */
---
key: value
---
/* comment */
.class {
display: none;
}
```
#### Support at-rule ends with right curly bracket ([#4733] by [@davidgomes])
In the prior version, at-rules that ended with `}` were not parsed correctly.
Prettier 1.14 now correctly recognizes and formats them.
<!-- prettier-ignore -->
```scss
/* Input */
@mixin placeholder {
&::placeholder {@content}
}
/* Output (Prettier 1.13) */
/*
SyntaxError: CssSyntaxError Unclosed block
*/
/* Output (Prettier 1.14) */
@mixin placeholder {
&::placeholder {
@content;
}
}
```
### Markdown
#### Preserve email autolink ([#4740] by [@ikatyang])
Autolinks are formatted as their url in the prior version, which is fine.
But theres a special case for email links that theyll be resolved as `mailto:` links.
In Prettier 1.14, email autolinks are preserved.
<!-- prettier-ignore -->
```md
<!-- Input -->
<hello@example.com>
<!-- Output (Prettier 1.13) -->
<mailto:hello@example.com>
<!-- Output (Prettier 1.14) -->
<hello@example.com>
```
#### Do not require space after markdown block language name ([#4783] by [@kachkaev])
In Prettier 1.12, we added the support for fenced codeblock lang followed by attributes,
which requires them to be separated by whitespaces.
But this introduced the inconsistency for codeblock highlighting in Atom that
codeblocks are highlighted but we do not format them.
2018-07-29 10:25:22 +03:00
We updated our detection logic in Prettier 1.14 so they should behave the same now.
<!-- prettier-ignore -->
````md
<!-- Input -->
```js{something=something}
const x = 1;
```
<!-- Output (Prettier 1.13) -->
```js{something=something}
const x = 1;
```
<!-- Output (Prettier 1.14) -->
```js{something=something}
const x = 1;
```
````
#### Use language aliases to find parser for markdown codeblocks ([#4734] by [@ikatyang])
Previously, we used the language `name` and `extensions` to determine which parser to use for codeblock formatting,
but we found that its impossible to format `JSON with Comments` codeblocks and keep syntax highlighter working at the same time
since they share the same `.json` extension with `JSON` and the comment syntax highlighting is only available in `JSON5`.
We added the support for using the language `aliases` to find parser in Prettier 1.14
so you should be able to use `jsonc` to format and trigger syntax highlighting for `JSON with Comments` codeblocks.
<!-- prettier-ignore -->
````md
<!-- Input -->
```jsonc
// comment
{"a":1}
```
<!-- Output (Prettier 1.13) -->
```jsonc
// comment
{"a":1}
```
<!-- Output (Prettier 1.14) -->
```jsonc
// comment
{ "a": 1 }
```
````
#### Preserve entity for encoded character if its code point is greater than U+FFFF ([#4832] by [@ikatyang])
The markdown parser we use (`remark`) parses every encoded character into a single AST node
so that were able to restore the encoded character by detecting if the value in the AST node is in length of 1.
But theres an exception that a single character can be in length of 2 if its code point is greater than 0xffff
since JavaScript uses UTF-16 (2 bytes) to encode strings.
Prettier 1.14 correctly recognizes these characters so they wont be transformed into the literal character.
<!-- prettier-ignore -->
````md
<!-- Input -->
&#x1F609;
<!-- Output (Prettier 1.13) -->
😉
<!-- Output (Prettier 1.14) -->
&#x1F609;
````
### Vue
#### Support range format for Vue files ([#4868] by [@ikatyang])
Previously, [range formatting](https://prettier.io/docs/en/options.html#range) was not available in Vue,
but Prettier 1.14 adds support for it.
### GraphQL
#### Preserve linebreak in non-block stringValue ([#4808] by [@ikatyang])
Non-block string values are only allowed to be in a single line
but Prettier 1.13 wrongly transformed the escaped `\n` into a real newline.
Prettier 1.14 now correctly prints `\n`.
<!-- prettier-ignore -->
```gql
# Input
{
foo(input: {multiline: "ab\ncd"}) { id }
}
# Output (Prettier 1.13)
{
foo(input: { multiline: "ab
cd" }) {
id
}
}
# Output (Prettier 1.14)
{
foo(input: { multiline: "ab\ncd" }) {
id
}
}
```
[@asottile]: https://github.com/asottile
[@davidgomes]: https://github.com/davidgomes
[@duailibe]: https://github.com/duailibe
[@eemeli]: https://github.com/eemeli
[@evilebottnawi]: https://github.com/evilebottnawi
[@ikatyang]: https://github.com/ikatyang
[@kachkaev]: https://github.com/kachkaev
[@karl]: https://github.com/karl
[@princed]: https://github.com/princed
[@sompylasar]: https://github.com/sompylasar
[@suchipi]: https://github.com/@suchipi
[@vojtechstep]: https://github.com/VojtechStep
[@warrenseine]: https://github.com/warrenseine
[#4563]: https://github.com/prettier/prettier/pull/4563
[#4601]: https://github.com/prettier/prettier/pull/4601
[#4625]: https://github.com/prettier/prettier/pull/4625
[#4657]: https://github.com/prettier/prettier/pull/4657
[#4667]: https://github.com/prettier/prettier/pull/4667
[#4688]: https://github.com/prettier/prettier/pull/4688
[#4695]: https://github.com/prettier/prettier/pull/4695
[#4697]: https://github.com/prettier/prettier/pull/4697
[#4699]: https://github.com/prettier/prettier/pull/4699
[#4701]: https://github.com/prettier/prettier/pull/4701
[#4706]: https://github.com/prettier/prettier/pull/4706
[#4713]: https://github.com/prettier/prettier/pull/4713
[#4717]: https://github.com/prettier/prettier/pull/4717
[#4721]: https://github.com/prettier/prettier/pull/4721
[#4733]: https://github.com/prettier/prettier/pull/4733
[#4734]: https://github.com/prettier/prettier/pull/4734
[#4740]: https://github.com/prettier/prettier/pull/4740
[#4742]: https://github.com/prettier/prettier/pull/4742
[#4748]: https://github.com/prettier/prettier/pull/4748
[#4757]: https://github.com/prettier/prettier/pull/4757
[#4762]: https://github.com/prettier/prettier/pull/4762
[#4773]: https://github.com/prettier/prettier/pull/4773
[#4777]: https://github.com/prettier/prettier/pull/4777
[#4778]: https://github.com/prettier/prettier/pull/4778
[#4783]: https://github.com/prettier/prettier/pull/4783
[#4790]: https://github.com/prettier/prettier/pull/4790
[#4808]: https://github.com/prettier/prettier/pull/4808
[#4823]: https://github.com/prettier/prettier/pull/4823
[#4830]: https://github.com/prettier/prettier/pull/4830
[#4832]: https://github.com/prettier/prettier/pull/4832
[#4836]: https://github.com/prettier/prettier/pull/4836
[#4848]: https://github.com/prettier/prettier/pull/4848
[#4852]: https://github.com/prettier/prettier/pull/4852
[#4854]: https://github.com/prettier/prettier/pull/4854
[#4868]: https://github.com/prettier/prettier/pull/4868
[#4885]: https://github.com/prettier/prettier/pull/4885
[#4893]: https://github.com/prettier/prettier/pull/4893