prettier/website/blog/2019-01-20-1.16.0.md

609 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
author: Ika (@ikatyang)
authorURL: https://github.com/ikatyang
title: "Prettier 1.16: HTML improvements and better CRLF handling"
---
This release improves HTML formatting and contains better CRLF handling, new
syntax features, and fixes several bugs.
<!--truncate-->
## Highlights
### HTML
#### Respect surrounding linebreaks ([#5596] by [@ikatyang])
Previously, Prettier always put elements in a single line if they didnt
go past the `printWidth`, but this doesnt work for elements that are used as
`if`-`else` blocks or are intended to contain several items. To solve this
problem, well respect surrounding linebreaks for all elements since there is
no reliable way to determine if theyre being used in these ways.
<!-- prettier-ignore -->
```html
<!-- Input -->
<div class="list">
<div class="item">Jan</div>
</div>
<a v-if="i !== -1" href="#" @click.prevent="select(i)">
{{ i }}
</a>
<span v-else>
<slot name="ellipsis">&hellip;</slot>
</span>
<!-- Output (Prettier 1.15) -->
<div class="list"><div class="item">Jan</div></div>
<a v-if="i !== -1" href="#" @click.prevent="select(i)"> {{ i }} </a>
<span v-else> <slot name="ellipsis">&hellip;</slot> </span>
<!-- Output (Prettier 1.16) -->
<div class="list">
<div class="item">Jan</div>
</div>
<a v-if="i !== -1" href="#" @click.prevent="select(i)">
{{ i }}
</a>
<span v-else>
<slot name="ellipsis">&hellip;</slot>
</span>
```
### General
#### Better CRLF handling ([#5494] by [@ikatyang])
You might have noticed a few weird formatting issues that only occurred on Windows.
Many of these issues were caused by our handling of CR-LF line endings.
In this release, we were able to resolve these issues by normalizing linebreaks
both before and after formatting.
### JavaScript
#### Improve the pattern used by React hooks ([#5608] by [@j-f1])
<!-- prettier-ignore -->
```js
// Input
function helloWorld() {
useEffect(() => {
// do something
}, [props.value])
}
// Output (Prettier 1.15)
function helloWorld() {
useEffect(
() => {
// do something
},
[props.value]
);
}
// Output (Prettier 1.16)
function helloWorld() {
useEffect(() => {
// do something
}, [props.value]);
}
```
#### Rename `babylon` parser to `babel` ([#5647] by [@wuweiweiwu])
Babels parser, `babylon`, was renamed to `@babel/parser` in Babel 7. Weve
renamed our `babylon` parser to `babel` as well to reduce confusion.
The `babylon` parser name is now deprecated but it still works.
If you need to change your config due to this change, please take a second to read
[our docs on the `parser` option], especially the note at the bottom.
[our docs on the `parser` option]: https://prettier.io/docs/en/configuration.html#setting-the-parser-docs-en-optionshtml-parser-option
### Flow
#### Add `babel-flow` parser ([#5685] by [@ikatyang])
Both the `babel` and `flow` parsers support Flow syntax by default, but there are a few
edge cases where Flow syntax is ambiguous. By default, Babels Flow parser will parse the
ambiguous code as regular JS, while the native Flow parser will parse it as Flow syntax.
To address this issue, we added the `babel-flow` parser option, which uses Babels parser,
but prefers Flow syntax when ambiguities arise.
<!-- prettier-ignore -->
```js
// Input
const Theme = React.createContext<"light" | "dark">("light");
// Output (Prettier 1.15, --parser babylon)
const Theme = (React.createContext < "light") | ("dark" > "light");
// Output (Prettier 1.16, --parser babel-flow)
const Theme = React.createContext<"light" | "dark">("light");
```
### CLI
#### Add a `--check` flag ([#5629] by [@kachkaev])
Passing `--list-different` to the `prettier` CLI command will cause Prettier to
exit with an error code if one or more of the files passed to it has not been
formatted with Prettier. This works great, but it doesnt provide any information
in the output except for the files which arent properly formatted. This isnt
very friendly for new contributors and users in general, so we added a `--check`
option that produces more human-friendly output.
<code style="display: block; background: #282a36; color: #f1f1f0">
<span style="color: #686868"># Prettier 1.15</span><br />
$ <span style="color: #5af78e">prettier</span> <span style="color: #57c7ff">\*.js</span> --list-different<br />
unformatted.js<br />
<br />
<span style="color: #686868"># Prettier 1.16</span><br />
$ <span style="color: #5af78e">prettier</span> <span style="color: #57c7ff">\*.js</span> --check<br />
Checking formatting...<br />
unformatted.js<br />
Code style issues found in the above file(s). Forgot to run Prettier?<br />
</code>
## Other changes
### General
#### Fix unexpected formatting caused by range format ([#5632] by [@lhchavez])
<!-- prettier-ignore -->
```js
// Input
something("something", () => {
const something = {
something: [
{
long1: "longlonglonglonglonglonglonglonglonglonglonglong",
long2: "longlonglonglonglonglonglonglonglonglonglonglong",
}
]
};
});
// Output (Prettier 1.15, --range-start 100 --range-end 120)
something("something", () => {
const something = { something: [{ long1: "longlonglonglonglonglonglonglonglonglonglonglong", long2: "longlonglonglonglonglonglonglonglonglonglonglong" }] };
});
// Output (Prettier 1.16, --range-start 100 --range-end 120)
something("something", () => {
const something = {
something: [
{
long1: "longlonglonglonglonglonglonglonglonglonglonglong",
long2: "longlonglonglonglonglonglonglonglonglonglonglong",
}
]
};
});
```
### API
#### Allow plugin instances to be passed in the `plugins` field of format options ([#5763] by [@Kingwl])
Previously, plugin instances were somehow disallowed to be passed in the
`plugins` field of format options but it should be allowed. We've fixed this
issue in Prettier 1.16.
```js
const prettier = require("prettier");
const fooPlugin = require("./path/to/foo-plugin");
const formatted = prettier.format("foo-code", {
plugins: [fooPlugin],
parser: "foo-parser"
});
// Prettier 1.15: Error
// Prettier 1.16: No error
```
### Standalone
#### Remove the dynamic `require()` call in the standalone bundle ([#5612] by [@j-f1])
Previously, a dynamic `require()` call was present in the `standalone.js` file designed
for usage in browsers. It was used in a way where it wasnt actually called, but
tools like webpack to throw a warning. We adjusted the build script to remove
this `require()` call in the standalone bundle in Prettier 1.16.
### TypeScript
#### Correctly handle `//` in TSX ([#5728] by [@JamesHenry])
Previously, putting `//` as a child of a JSX element in TypeScript led to an error
because it was interpreted as a comment. Prettier 1.16 fixes this issue.
<!-- prettier-ignore -->
```js
// Input
const link = <a href="example.com">http://example.com</a>
// Output (Prettier 1.15)
// Error: Comment location overlaps with node location
// Output (Prettier 1.16)
const link = <a href="example.com">http://example.com</a>;
```
#### Remove redundant parentheses around type annotations ([#5724] by [@flurmbo])
<!-- prettier-ignore -->
```js
// Input
class Foo {
bar: (() => boolean);
}
// Output (Prettier 1.15)
class Foo {
bar: (() => boolean);
}
// Output (Prettier 1.16)
class Foo {
bar: () => boolean;
}
```
### JavaScript
#### Do not treat `something.connect()` as functional composition ([#5739] by [@makepost])
A special format for `connect()` calls was introduced to improve formatting of Redux
several versions ago, but there are many other uses for functions named `connect` that
shouldnt be formatted that way. Since most of these cases involved a `connect` method,
we no longer treat `foo.connect()` calls as functional composition.
<!-- prettier-ignore -->
```js
// Input
app.connect("activate", async () => {
await data.load();
win.show_all();
});
const ConnectedComponent = connect(
bar,
baz
)(foo);
// Output (Prettier 1.15)
app.connect(
"activate",
async () => {
await data.load();
win.show_all();
}
);
const ConnectedComponent = connect(
bar,
baz
)(foo);
// Output (Prettier 1.16)
app.connect("activate", async () => {
await data.load();
win.show_all();
});
const ConnectedComponent = connect(
bar,
baz
)(foo);
```
#### Add support for class private methods ([#5637] by [@existentialism])
```js
// Input
class Hello {
#world() {}
}
// Output (Prettier 1.15)
// SyntaxError
// Output (Prettier 1.16)
class Hello {
#world() {}
}
```
#### Correct indentation for expressions in root template ([#5607] by [@ikatyang])
<!-- prettier-ignore -->
```js
// Input
if (a) {
return `
hello
${foo({
bar,
baz
})}
world
`;
}
// Output (Prettier 1.15)
if (a) {
return `
hello
${foo({
bar,
baz
})}
world
`;
}
// Output (Prettier 1.16)
if (a) {
return `
hello
${foo({
bar,
baz
})}
world
`;
}
```
#### Remove unnecessary linebreaks from HTML template literals ([#5771] by [@ikatyang])
<!-- prettier-ignore -->
```js
// Input
function HelloWorld() {
return html`
<h3>Bar List</h3>
${bars.map(bar => html`
<p>${bar}</p>
`)}
`;
}
// Output (Prettier 1.15)
function HelloWorld() {
return html`
<h3>Bar List</h3>
${
bars.map(
bar => html`
<p>${bar}</p>
`
)
}
`;
}
// Output (Prettier 1.16)
function HelloWorld() {
return html`
<h3>Bar List</h3>
${bars.map(
bar => html`
<p>${bar}</p>
`
)}
`;
}
```
### TypeScript/Flow
#### Correctly recognize `/* HTML */` templates ([#5658] by [@ikatyang])
We [added support] for HTML template literal formatting using the `/* HTML */` pseudo-tag
in Prettier 1.15, but due to a bug, it only worked for JavaScript code. Weve fixed this
issue in Prettier 1.16.
[added support]: https://prettier.io/blog/2018/11/07/1.15.0.html#html-template-literal-in-javascript
### CSS
#### Fix broken output for lists caused by comments ([#5710] by [@jsnajdr])
<!-- prettier-ignore -->
```scss
// Input
$my-list2:
a // a
b
c;
// Output (Prettier 1.15)
$my-list2: a// a
bc;
// Output (Prettier 1.16)
$my-list2: a // a
b c;
```
#### Correctly handle backslashes ([#5597] by [@sh7dm])
<!-- prettier-ignore -->
```less
// Input
.figcaption {
.margin-top-1\/2;
.large\:none;
}
// Output (Prettier 1.15)
.figcaption {
.margin-top-1\ / 2;
.large\: none;
}
// Output (Prettier 1.16)
.figcaption {
.margin-top-1\/2;
.large\: none;
}
```
### MDX
#### Correctly handle inline html ([#5704] by [@ikatyang])
<!-- prettier-ignore -->
```md
<!-- Input -->
| Column 1 | Column 2 |
|---|---|
| Text | <Hello>Text</Hello> |
<!-- Output (Prettier 1.15) -->
<!-- SyntaxError -->
<!-- Output (Prettier 1.16) -->
| Column 1 | Column 2 |
| -------- | ------------------- |
| Text | <Hello>Text</Hello> |
```
### HTML
#### Format script with type "application/ld+json" ([#5642] by [@ikatyang])
<!-- prettier-ignore -->
```html
<!-- Input -->
<script type="application/ld+json">
{ "json":true }
</script>
<!-- Output (Prettier 1.15) -->
<script type="application/ld+json">
{ "json":true }
</script>
<!-- Output (Prettier 1.16) -->
<script type="application/ld+json">
{ "json": true }
</script>
```
#### Treat `.mjml` files as HTML ([#5505] by [@n1ru4l])
MJML is a markup language that uses the same syntax as HTML. We added the `.mjml`
file extension to the list of extensions that are recognized as HTML, so Prettier
will format it.
#### Smart quote for attributes ([#5590] by [@ikatyang])
Previously, the quotes around HTML attribute values were always printed as double
quotes. To improve readability, they are now printed as the quote type that results
in fewer escape characters being required in the string, like we do for other strings.
<!-- prettier-ignore -->
```html
<!-- Input -->
<div x='123"456'></div>
<div x="123'456"></div>
<!-- Output (Prettier 1.15) -->
<div x="123&quot;456"></div>
<div x="123'456"></div>
<!-- Output (Prettier 1.16) -->
<div x='123"456'></div>
<div x="123'456"></div>
```
### Vue
#### Tag names are case-sensitive ([#5606] by [@ikatyang])
Previously, we lowercased tag names before querying tag definition while
parsing, which caused `<Input>` component to be recognized as a native `<input>`.
This would produce a syntax error when `</Input>` was encountered since `<input>`
is a void element, and void elements cant have closing elements.
Weve fixed this issue in 1.16.
<!-- prettier-ignore -->
```vue
<!-- Input -->
<template>
<Input></Input>
</template>
<!-- Output (Prettier 1.15) -->
<!-- SyntaxError -->
<!-- Output (Prettier 1.16) -->
<template>
<Input></Input>
</template>
```
### Vue/Angular
#### Add parentheses to avoid unexpected `}}` in interpolations ([#5657] by [@ikatyang])
`}}` is not allowed to be used in a interpolation since itll be recognized as the
end of the interpolation. Prettier 1.15 would sometimes output code that broke this
rule. Prettier 1.16 now adds parentheses to prevent `}}` from appearing in interpolations.
<!-- prettier-ignore -->
```html
<!-- Input -->
<p>{{ foo({ bar: {} }) }}</p>
<!-- First Output (Prettier 1.15, --no-bracket-spacing) -->
<p>{{ foo({bar: {}}) }}</p>
<!-- Second Output (Prettier 1.15, --no-bracket-spacing) -->
<!-- SyntaxError -->
<!-- Output (Prettier 1.16, --no-bracket-spacing) -->
<p>{{ foo({bar: ({})}) }}</p>
```
[@existentialism]: https://github.com/existentialism
[@flurmbo]: https://github.com/flurmbo
[@ikatyang]: https://github.com/ikatyang
[@j-f1]: https://github.com/j-f1
[@jameshenry]: https://github.com/JamesHenry
[@jsnajdr]: https://github.com/jsnajdr
[@kachkaev]: https://github.com/kachkaev
[@kingwl]: https://github.com/Kingwl
[@lhchavez]: https://github.com/lhchavez
[@makepost]: https://github.com/makepost
[@n1ru4l]: https://github.com/n1ru4l
[@sh7dm]: https://github.com/sh7dm
[@wuweiweiwu]: https://github.com/wuweiweiwu
[#5494]: https://github.com/prettier/prettier/pull/5494
[#5505]: https://github.com/prettier/prettier/pull/5505
[#5590]: https://github.com/prettier/prettier/pull/5590
[#5596]: https://github.com/prettier/prettier/pull/5596
[#5597]: https://github.com/prettier/prettier/pull/5597
[#5606]: https://github.com/prettier/prettier/pull/5606
[#5607]: https://github.com/prettier/prettier/pull/5607
[#5608]: https://github.com/prettier/prettier/pull/5608
[#5612]: https://github.com/prettier/prettier/pull/5612
[#5629]: https://github.com/prettier/prettier/pull/5629
[#5632]: https://github.com/prettier/prettier/pull/5632
[#5637]: https://github.com/prettier/prettier/pull/5637
[#5642]: https://github.com/prettier/prettier/pull/5642
[#5647]: https://github.com/prettier/prettier/pull/5647
[#5657]: https://github.com/prettier/prettier/pull/5657
[#5658]: https://github.com/prettier/prettier/pull/5658
[#5685]: https://github.com/prettier/prettier/pull/5685
[#5704]: https://github.com/prettier/prettier/pull/5704
[#5710]: https://github.com/prettier/prettier/pull/5710
[#5724]: https://github.com/prettier/prettier/pull/5724
[#5728]: https://github.com/prettier/prettier/pull/5728
[#5739]: https://github.com/prettier/prettier/pull/5739
[#5763]: https://github.com/prettier/prettier/pull/5763
[#5771]: https://github.com/prettier/prettier/pull/5771