website/blog/2018-11-07-1.15.0.md
This release adds support for HTML, Vue, Angular and MDX. It also respects decorator position, adds an option for JSX single quotes, allows parser inference via shebang, adds support for several new syntax features, and has a few formatting tweaks.
<!-- truncate -->Prettier can now format HTML, Vue and Angular files! 🎉
We use angular-html-parser, an HTML parser extracted from Angular, to parse these HTML and HTML template files so it should be highly compliant with the HTML spec thanks to the Angular team.
A few highlights:
As you may notice during daily HTML works, the following two cases won't produce the same output:
| html | output | |
|---|---|---|
| with spaces | 1<b> 2 </b>3 | 1<b> 2 </b>3 |
| without spaces | 1<b>2</b>3 | 1<b>2</b>3 |
This happens because whitespace is significant in inline elements.
For this reason, we cannot safely format
<!-- prettier-ignore --><a href="https://prettier.io/">Prettier is an opinionated code formatter.</a>
into
<!-- prettier-ignore --><a href="https://prettier.io/">
Prettier is an opinionated code formatter.
</a>
since it may modify the displayed output in the browser.
Instead of breaking your code or just doing nothing, we introduce whitespace-sensitive formatting, which:
display value for every element to identify if the whitespace inside it is significant,For example:
<!-- prettier-ignore --><!-- <span> is an inline element, <div> is a block element -->
<!-- input -->
<span class="dolorum atque aspernatur">Est molestiae sunt facilis qui rem.</span>
<div class="voluptatem architecto at">Architecto rerum architecto incidunt sint.</div>
<!-- output -->
<span class="dolorum atque aspernatur"
>Est molestiae sunt facilis qui rem.</span
>
<div class="voluptatem architecto at">
Architecto rerum architecto incidunt sint.
</div>
We also allow magic comments (e.g., <!-- display: block -->) to tell Prettier how to format elements
due to the fact that CSS display can be changed:
<!-- input -->
<!-- display: block -->
<span class="dolorum atque aspernatur">Est molestiae sunt facilis qui rem.</span>
<!-- output -->
<!-- display: block -->
<span class="dolorum atque aspernatur">
Est molestiae sunt facilis qui rem.
</span>
There's also an option for the global whitespace sensitivity in case you may want maximum safety or you just don't care about that whitespace:
--html-whitespace-sensitivity (defaults to css)
css - Respect the default value of CSS display property.strict - All whitespace is considered significant.ignore - All whitespace is considered insignificant.Prettier uses filename to infer which parser to use. Here's the default patterns for HTML, Vue, and Angular:
*.html: --parser html*.component.html: --parser angular*.vue: --parser vueMake sure your filename matches the correct parser (especially for Angular users); if it does not, you will have to manually specify which parser to use via the overrides field.
Note that framework-specific formatting won't be triggered in --parser html.
This release also adds support for the html template tag (or a “tag” comment containing HTML):
html`code`/* HTML */ `code`// input
const foo = html`<div class="voluptatem architecto at">Architecto rerum ${interpolation} architecto incidunt sint.</div>`;
// output
const foo = html`
<div class="voluptatem architecto at">
Architecto rerum ${interpolation} architecto incidunt sint.
</div>
`;
The following Vue-specific syntax structures are supported:
{{ something }}v-something:something@somethingv-forslot-scopeThe following Angular-specific syntax structures are supported:
{{ something }}(something)[something][(something)]*something@Component({ template: `<div>Hello World</div>` })MDX is a markdown extension that lets you use JSX to build cool documentation. You can now use Prettier to format it, and we’ll format both the Markdown and JS pieces for you!
<!-- prettier-ignore --><!-- Input -->
import {
colors } from
'./theme'
import Palette from './components/palette'
# Colors
<Palette colors={
colors}
/>
<!-- Output -->
import { colors } from "./theme";
import Palette from "./components/palette";
# Colors
<Palette colors={colors} />
Previously, nested ternaries were always indented, which caused increasing levels of indentation for deeply-nested ternaries.
To solve this problem, we flattened the else-branch for nested ternaries in a fashion similar to how if..else if..else blocks are formatted.
// Input
const example1 =
someValue === 'a' ? 'hello world, branch a'
: someValue === 'b' ? 'hello world, branch a && b'
: someValue === 'c' ? 'hello world, branch a && b && c'
: someValue === 'd' ? 'hello world, branch a && b && c && d'
: null;
const example2 =
someValue === 'a'
? someValue === 'b'
? someValue === 'c'
? 'hello world, branch a && b && c'
: 'hello world, branch a && b && !c'
: 'hello world, branch a && !b'
: null;
// Output (Prettier 1.14)
const example1 =
someValue === "a"
? "hello world, branch a"
: someValue === "b"
? "hello world, branch a && b"
: someValue === "c"
? "hello world, branch a && b && c"
: someValue === "d"
? "hello world, branch a && b && c && d"
: null;
const example2 =
someValue === "a"
? someValue === "b"
? someValue === "c"
? "hello world, branch a && b && c"
: "hello world, branch a && b && !c"
: "hello world, branch a && !b"
: null;
// Output (Prettier 1.15)
const example1 =
someValue === "a"
? "hello world, branch a"
: someValue === "b"
? "hello world, branch a && b"
: someValue === "c"
? "hello world, branch a && b && c"
: someValue === "d"
? "hello world, branch a && b && c && d"
: null;
const example2 =
someValue === "a"
? someValue === "b"
? someValue === "c"
? "hello world, branch a && b && c"
: "hello world, branch a && b && !c"
: "hello world, branch a && !b"
: null;
Prior to Prettier 1.14, we were always placing decorators on the same line as what they were decorating.
We received feedback from some users that this was not ideal formatting, so after consideration, we changed it and in Prettier 1.14, decorators were always placed on a separate line from what they were decorating.
However, we received feedback from other users that this formatting was not ideal in all cases.
We want to have consistent formatting in Prettier when we can, so we tried to think of a heuristic that we could use to decide when to put decorators on the same line and when to put them on another line.
However, after a long discussion in #4924, we concluded that there's no reliable way to identify which should be inlined and which shouldn't be, so in Prettier 1.15 we decided to respect the original style that the user wrote. So if they put a newline between the decorator and what it decorates, we will print a newline there. If they didn't, we won't.
<!-- prettier-ignore -->// Input
class Hello {
@decorator inline = 'value';
@decorator
ownLine = 'value';
@decorator({
hello: 'world'
}) multiLine = 'value';
}
// Output (Prettier 1.14)
class Hello {
@decorator
inline = "value";
@decorator
ownLine = "value";
@decorator({
hello: "world"
})
multiLine = "value";
}
// Output (Prettier 1.15)
class Hello {
@decorator inline = "value";
@decorator
ownLine = "value";
@decorator({
hello: "world"
})
multiLine = "value";
}
Decorators are still not part of the official ECMA standard and where decorators on exported classes should go is a question whose answer has not yet been decided. To help proposal authors to get feedback, Babel 7 added support for both decorators before and after the exported classes. Prettier 1.15 adds support for them and respects where you put the decorator(s). (Once the spec is standardized, we'll change it to be consistent and not respect user input.)
<!-- prettier-ignore -->// decorator before export
@decorator export class Bar {}
// decorator after export
export @decorator class Foo {}
Previously, Prettier would automatically break objects onto multiple lines if they didn’t fit within the print width.
Prettier would also keep objects broken onto multiple lines if there was a newline somewhere inside them in the input code.
This made it difficult to collapse an object since you had to manually merge the object onto one line.
Since manual formatting changes are a task Prettier aims to eliminate, we’ve changed the behavior to only check for a newline between the { and the first key:
// Input
const data = { foo: 'bar',
baz: 'quux'
}
/* You’d get this format by deleting the newline after the `{` */
// Output (Prettier 1.14)
const data = {
foo: 'bar',
baz: 'quux'
}
// Output (Prettier 1.15)
const data = { foo: 'bar', baz: 'quux' }
After huge demand from the community,
Prettier 1.15 adds an option for printing single quotes in JSX: --jsx-single-quote (or jsxSingleQuote in the config/API).
// with --jsx-single-quote
<div class='hello'>world</div>
// without --jsx-single-quote
<div class="hello">world</div>
Prettier 1.14 accidentally introduced some very unfortunate line breaks in JSX. Those cases have now been fixed.
<!-- prettier-ignore -->// Input
<div>
Sales tax estimated using a rate of {salesTax * 100}%.
</div>;
<BasicText light>(avg. {value}/5)</BasicText>;
<Link to={orgURL(this.props.org.name)}>
Go to {this.props.org.name}'s profile
</Link>;
// Output (Prettier 1.14)
<div>
Sales tax estimated using a rate of {salesTax * 100}
%.
</div>;
<BasicText light>
(avg. {value}
/5)
</BasicText>;
<Link to={orgURL(this.props.org.name)}>
Go to {this.props.org.name}
's profile
</Link>;
// Output (Prettier 1.15)
<div>Sales tax estimated using a rate of {salesTax * 100}%.</div>;
<BasicText light>(avg. {value}/5)</BasicText>;
<Link to={orgURL(this.props.org.name)}>
Go to {this.props.org.name}'s profile
</Link>;
The Flow team plans to treat all object types as exact by default in the future, so they introduced a new syntax to indicate if an object type is inexact. This syntax is now supported in Prettier 1.15.
<!-- prettier-ignore -->type T = {
a: number,
...
}
Previously, parentheses that surrounds Flow typecast comments were sometimes removed, which would break Flow's comment syntax. This issue has been fixed in Prettier 1.15.
<!-- prettier-ignore -->// Input
(obj /*: Class */).property
// Output (Prettier 1.14)
obj /*: Class */.property;
// Output (Prettier 1.15)
(obj /*: Class */).property;
Previously, some of remark-math's syntax structures were mangled since we treated them as normal text. They are now preserved in Prettier 1.15 so you can safely use math syntax.
<!-- prettier-ignore -->$inline-math$
$$
block-math
$$
Previously, we used filename and extension to infer which parser to use, but often there's no extension for CLI scripts, so the user has to specify the parser manually, which is not ideal. In Prettier 1.15, when formatting a file with no extension, we'll look at the first line of the file, and if there's a shebang, we'll use it to infer which parser to use.
<code style={{display: "block", background: "#282a36", color: "#f1f1f0"}}> <span style={{color: "#686868"}}># Input</span>
$ <span style={{color: "#5af78e"}}>cat</span> <u>bin/example</u>
#!/usr/bin/env node
require ( "../src/cli" ) . run ( )
$ <span style={{color: "#5af78e"}}>prettier</span> <u>bin/example</u>
<span style={{color: "#686868"}}># Output (Prettier 1.14)</span>
[<span style={{color: "#ff5c57"}}>error</span>] No parser could be inferred for file: bin/example
<span style={{color: "#686868"}}># Output (Prettier 1.15)</span>
#!/usr/bin/env node
require("../src/cli").run(); </code>
trim command to trim whitespaces in the current line (#4772 by @warrenseine)Previously in the plugin API, there was no method to delete the current line’s indentation.
It's possible to use some workarounds to achieve the same goal, but there wasn't a reliable workaround,
so we introduced a new trim command to trim whitespaces in a reliable way.
Previously, there was no color for the option validation error message, so it wasn’t easy to see what option had an invalid value passed to it, and what the valid values were. In Prettier 1.15, you should be able to understand what's going on at a glance.
<code style={{display: "block", background: "#282a36", color: "#f1f1f0"}}> <span style={{color: "#686868"}}># Input</span>
$ <span style={{color: "#5af78e"}}>prettier</span> <u>filename.js</u> --trailing-comma wow
<span style={{color: "#686868"}}># Output (Prettier 1.14)</span>
[<span style={{color: "#ff5c57"}}>error</span>] Invalid ``--trailing-comma`` value. Expected "all", "es5" or "none", but received `"wow"`.
<span style={{color: "#686868"}}># Output (Prettier 1.15)</span>
[<span style={{color: "#ff5c57"}}>error</span>] Invalid <span style={{color: "#ff5c57"}}>--trailing-comma</span> value. Expected <span style={{color: "#57c7ff"}}>"all", "es5" or "none"</span>, but received <span style={{color: "#ff5c57"}}>"wow"</span>. </code>
Sometimes we need to transform the AST to make it easier to print.
Previously, it was done in the parser but this way it also exposed the internal stuff to external users,
who may have tried to build a custom parser, which is not ideal.
In Prettier 1.15, you can now use printer.preprocess to preprocess the AST without exposing any internals of the API.
interface Printer {
preprocess(ast: AST, options: object): AST;
}
Previously, loading a config file of an unsupported format would throw an error message that looks like a bug in Prettier, so we improved the message in Prettier 1.15.
<code style={{display: "block", background: "#282a36", color: "#f1f1f0"}}> <span style={{color: "#686868"}}># Input</span>
$ <span style={{color: "#5af78e"}}>prettier</span> <u>filename.js</u> --config <u>.prettierrc.wow</u>
<span style={{color: "#686868"}}># Output (Prettier 1.14)</span>
[<span style={{color: "#ff5c57"}}>error</span>] Invalid configuration file: Cannot read property 'sync' of undefined
<span style={{color: "#686868"}}># Output (Prettier 1.15)</span>
[<span style={{color: "#ff5c57"}}>error</span>] Invalid configuration file: No sync loader specified for extension ".wow" </code>
Previously, Prettier always respected your original line endings, which is fine in the most cases.
But when people collaborate on a project from different operating systems,
it becomes easy to end up with mixed line endings in the central git repository and cause large diffs.
Prettier 1.15 adds an option --end-of-line <auto|lf|crlf|cr> to help you deal with these line ending issues.
Prettier will now properly indent JSDoc-style comments with only a single * on the first line (/* vs /**) when the comment’s indentation changes:
// Input
if (true) {
/*
* Oh no
*/
}
// Output (Prettier 1.14)
if (true) {
/*
* Oh no
*/
}
// Output (Prettier 1.15)
if (true) {
/*
* Oh no
*/
}
Previously, parentheses for mixed exponentiation/modulo were wrongly removed, but we fixed this in Prettier 1.15.
<!-- prettier-ignore -->// Input
const val = (n % 10) ** 2
// Output (Prettier 1.14)
const val = n % 10 ** 2;
// Output (Prettier 1.15)
const val = (n % 10) ** 2;
try..finally (#5252 by @aquibm)In previous versions, some comments in a try-finally statement were printed in the wrong order.
Prettier now prints them correctly.
// Input
// comment 1
try {
// comment 2
}
// comment 3
finally // comment 4
{
// comment 5
}
// Output (Prettier 1.14)
// comment 1
try {
// comment 2
} finally { // comment 4
// comment 3
// comment 5
}
// Output (Prettier 1.15)
// comment 1
try {
// comment 2
} finally {
// comment 3
// comment 4
// comment 5
}
Comments in catch clauses are now printed on their own line just like other clauses.
// Input
try {} catch (
// comment
e
) {}
// Output (Prettier 1.14)
try {
} catch (// comment
e) {}
// Output (Prettier 1.15)
try {
} catch (
// comment
e
) {}
There's no need to add an extra indentation level for a function call argument that's an arrow function with conditional expression as body. We now inline them in Prettier 1.15.
<!-- prettier-ignore -->// Input
x.then(() => a ?
veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong:
veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
// Output (Prettier 1.14)
x.then(
() =>
a
? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
: veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
// Output (Prettier 1.15)
x.then(() =>
a
? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
: veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
In previous versions, comments in variable declarations caused variable declarators to be printed without indentation, but this has been fixed in Prettier 1.15.
<!-- prettier-ignore -->// Input
const // Comment
a = 1;
// Output (Prettier 1.14)
const // Comment
a = 1;
// Output (Prettier 1.15)
const // Comment
a = 1;
Prettier 1.14 was incorrectly removing parens around ternary operators when they appeared within optional member expressions (?.). Those cases are now printed correctly in Prettier 1.15.
// Input
(a ? b : c)?.d;
// Output (Prettier 1.14)
a ? b : c?.d;
// Output (Prettier 1.15)
(a ? b : c)?.d;
${ as well as backticks in GraphQL tags (#5137 by @lydell)Previously, interpolation-like strings were wrongly unescaped in embedded GraphQL, which led to JavaScript treating it as an interpolation. They're correctly escaped in Prettier 1.15.
<!-- prettier-ignore -->// Input
const schema = gql`
type Project {
"Pattern: \`\${project}\`"
pattern: String
}
`;
// Output (Prettier 1.14)
const schema = gql`
type Project {
"Pattern: \`${project}\`"
pattern: String
}
`;
// Output (Prettier 1.15)
const schema = gql`
type Project {
"Pattern: \`\${project}\`"
pattern: String
}
`;
Previously, Prettier stripped quotes in keys if they weren’t necessary in ES2015, which caused the output to be incompatible with ES5. Prettier 1.15 only strips them if they're not necessary in ES5.
<!-- prettier-ignore -->// Input
var obj = {
"𐊧": 'ok',
𐊧: 'ok'
};
// Output (Prettier 1.14)
var obj = {
𐊧: "ok",
𐊧: "ok"
};
// Output (Prettier 1.15)
var obj = {
"𐊧": "ok",
𐊧: "ok"
};
We have some special cases that will hug function call arguments if the first one is a function and the second one is a not a complex expression, but we considered ternaries non-complex expressions. They actually can be complex, so we’ve changed this in Prettier 1.15.
<!-- prettier-ignore -->// Input
func(
() => { thing(); },
something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0)
);
// Output (Prettier 1.14)
func(() => {
thing();
}, something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0));
// Output (Prettier 1.15)
func(
() => {
thing();
},
something(longArgumentName, anotherLongArgumentName)
? someOtherThing()
: somethingElse(true, 0)
);
This preserves Prettier’s special formatting for testing functions when a timeout (number) is passed as a third parameter:
<!-- prettier-ignore -->// Input
it('Handles at least 10k untracked files without failing', async () => {
hello()
}, 25000)
// Output (Prettier 1.14)
it(
"Handles at least 10k untracked files without failing",
async () => {
hello();
},
25000
);
// Output (Prettier 1.15)
it('Handles at least 10k untracked files without failing', async () => {
hello()
}, 25000)
Previously, arguments in beforeEach were wrongly hugged. We've fixed this issue in Prettier 1.15.
// Input
beforeEach(done =>
startService()
.pipe(tap(service => (instance = service)))
.subscribe(() => done()),
);
// Output (Prettier 1.14)
beforeEach(done =>
startService()
.pipe(tap(service => (instance = service)))
.subscribe(() => done()));
// Output (Prettier 1.15)
beforeEach(done =>
startService()
.pipe(tap(service => (instance = service)))
.subscribe(() => done())
);
In Prettier 1.14, a comment in front of a pipeline operator causes the right argument to be not indented. This issue has been fixed in Prettier 1.15.
<!-- prettier-ignore -->// Input
function pipeline() {
0
// Comment
|> x
}
// Output (Prettier 1.14)
function pipeline() {
0
|> // Comment
x;
}
// Output (Prettier 1.15)
function pipeline() {
0 |>
// Comment
x;
}
new expressions (#5017 by @flxwu)Passing a comment instead of an expression to a new call is now preserved
instead of being pulled out of the parens.
// Input
new Thing(/* comment */)
// Output (Prettier 1.14)
new Thing /* comment */();
// Output (Prettier 1.15)
new Thing(/* comment */);
Unnecessary semicolons for bind expressions are removed with --no-semi in Prettier 1.15.
// Input
a::b.c
// Output (Prettier 1.14)
;a::b.c
// Output (Prettier 1.15)
a::b.c
Necessary parens in bind expressions are preserved in Prettier 1.15.
<!-- prettier-ignore -->// Input
a::(b.c());
// Output (Prettier 1.14)
a::b.c();
// Output (Prettier 1.15)
a::(b.c());
Logical expressions in a ternary in a function call are now indented correctly.
<!-- prettier-ignore -->// Input
fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol // <--
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// Output (Prettier 1.14)
fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol // <--
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
// Output (Prettier 1.15)
fn(
bifornCringerMoshedPerplexSawder,
askTrovenaBeenaDependsRowans,
glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
anodyneCondosMalateOverateRetinol // <--
? annularCooeedSplicesWalksWayWay
: kochabCooieGameOnOboleUnweave
);
imports (#5016 by @ericsakmar)Comments in imports won't be moved output of the import.
// Input
import x, {
// comment
y
} from 'z';
// Output (Prettier 1.14)
import x, { y } from "z";
// comment
// Output (Prettier 1.15)
import x, {
// comment
y
} from "z";
while comment (#5251 by @jaideng123)Comments in while are now correctly formatted
so that it does not need to be formatted twice to get to a stable output.
// Input
while(
true
// Comment
) {}
// First Output (Prettier 1.14)
while (true) // Comment
{}
// Second Output (Prettier 1.14)
while (
true // Comment
) {}
// First & Second Output (Prettier 1.15)
while (
true
// Comment
) {}
Comments between a function declaration and its body do not need to be formatted twice to get the final result now.
<!-- prettier-ignore -->// Input
function foo() // this is a function
{
return 42
}
// First Output (Prettier 1.14)
function foo() { // this is a function
return 42;
}
// Second Output (Prettier 1.14)
function foo() {
// this is a function
return 42;
}
// First & Second Output (Prettier 1.15)
function foo() {
// this is a function
return 42;
}
Unnecessary indentations for logical expression chains in JSX are now prevented.
<!-- prettier-ignore -->// Input
const TestComponent = () => {
return (
<>
{cats && memes && (
<Foo bar><Trololol /></Foo>
)}
</>
);
}
// Output (Prettier 1.14)
const TestComponent = () => {
return (
<>
{cats &&
memes && (
<Foo bar>
<Trololol />
</Foo>
)}
</>
);
};
// Output (Prettier 1.15)
const TestComponent = () => {
return (
<>
{cats && memes && (
<Foo bar>
<Trololol />
</Foo>
)}
</>
);
};
Previously, non-breaking whitespaces were treated as regular whitespaces, which caused them to be replaced with regular whitespaces. This issue has been fixed in Prettier 1.15.
(· represents a non-breaking whitespace)
// Input
function OhMyWhitespace() {
return (
<Dialog>
<p>
Supprimer l’objectif «·{goal.name}·»·?
</p>
</Dialog>
)
}
// Output (Prettier 1.14)
function OhMyWhitespace() {
return (
<Dialog>
<p>
Supprimer l’objectif «
{goal.name}
·»·?
</p>
</Dialog>
);
}
// Output (Prettier 1.15)
function OhMyWhitespace() {
return (
<Dialog>
<p>Supprimer l’objectif «·{goal.name}·»·?</p>
</Dialog>
);
}
Simple jsx opening tags are no longer broken onto multiple lines.
<!-- prettier-ignore -->// Input
function HelloWorld() {
const listItemText = (
<ListItemText
primary={
<PrimaryText>{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
}
/>
);
}
// Output (Prettier 1.14)
function HelloWorld() {
const listItemText = (
<ListItemText
primary={
<PrimaryText
>{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
}
/>
);
}
// Output (Prettier 1.15)
function HelloWorld() {
const listItemText = (
<ListItemText
primary={
<PrimaryText>{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
}
/>
);
}
// Input
<div className="search-filter-chips">
{scopes.filter(scope => scope.value !== "").map((scope, i) => (
<FilterChip
query={this.props.query}
onFilterChosen={this.onSearchScopeClicked}
/>
))}
</div>;
// Output (Prettier 1.14)
<div className="search-filter-chips">
{scopes.filter(scope => scope.value !== "").map((scope, i) => (
<FilterChip
query={this.props.query}
onFilterChosen={this.onSearchScopeClicked}
/>
))}
</div>;
// Output (Prettier 1.15)
<div className="search-filter-chips">
{scopes
.filter(scope => scope.value !== "")
.map((scope, i) => (
<FilterChip
query={this.props.query}
onFilterChosen={this.onSearchScopeClicked}
/>
))}
</div>;
Generics with a single identifier are now always inlined.
<!-- prettier-ignore -->// Input
const longVariableName: Array<number> = this.foo.bar.baz.collider.body.vertices.reduce();
// Output (Prettier 1.14)
const longVariableName: Array<
number
> = this.foo.bar.baz.collider.body.vertices.reduce();
// Output (Prettier 1.15)
const longVariableName: Array<number> = this.foo.bar.baz.collider.body.vertices.reduce();
extends (#5244 by @aquibm)Classes in extends are now correctly broken into multiple lines.
// Input
declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
x: string;
}
// Output (Prettier 1.14)
declare interface ExtendsMany
extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
x: string;
}
// Output (Prettier 1.15)
declare interface ExtendsMany
extends Interface1,
Interface2,
Interface3,
Interface4,
Interface5,
Interface6,
Interface7 {
x: string;
}
export default (#5303 by @jbrown215)Unnecessary parens around export default async function are now removed.
This error occurred only when using the flow parser.
// Input
export default async function foo() {};
// Output (Prettier 1.14)
export default (async function foo() {});
// Output (Prettier 1.15)
export default async function foo() {}
Necessary semicolons for non-null assertions won't be removed in --no-semi mode.
// Input
const el = ReactDOM.findDOMNode(ref)
;(el as HTMLElement)!.style.cursor = 'pointer'
// Output (Prettier 1.14)
const el = ReactDOM.findDOMNode(ref)
(el as HTMLElement)!.style.cursor = "pointer"
// Output (Prettier 1.15)
const el = ReactDOM.findDOMNode(ref)
;(el as HTMLElement)!.style.cursor = "pointer"
prettier-ignore is used (#5160 by @onurtemizkan)Extra semicolon for method signature is removed in Prettier 1.15.
<!-- prettier-ignore -->// Input
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
// prettier-ignore
addEventListener(): void;
addEventListener(type: string): void;
}
// Output (Prettier 1.14)
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
// prettier-ignore
addEventListener(): void;;
addEventListener(type: string): void;
}
// Output (Prettier 1.15)
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
// prettier-ignore
addEventListener(): void;
addEventListener(type: string): void;
}
Previously, Prettier printed invalid parens for destructuring with default value, we fixed this issue in Prettier 1.15.
<!-- prettier-ignore -->// Input
({ prop: toAssign = "default" } = { prop: "propval" });
// Output (Prettier 1.14)
({ prop: (toAssign = "default") } = { prop: "propval" });
// Output (Prettier 1.15)
({ prop: toAssign = "default" } = { prop: "propval" });
--no-semi mode (#5083 by @ikatyang)In Prettier 1.14, semicolons are added to the end of a class property when there are modifiers in its next property, however these semicolons are not needed. Unnecessary semicolons are removed in Prettier 1.15.
<!-- prettier-ignore -->// Input
class Reader {
private [kBuffer]: Buffer
private [kOffset]: number
}
// Output (1.14)
class Reader {
private [kBuffer]: Buffer;
private [kOffset]: number
}
// Output (1.15)
class Reader {
private [kBuffer]: Buffer
private [kOffset]: number
}
extends (#5074 by @ikatyang)Previously, parens for complex nodes in class expression's extends were wrongly removed, producing invalid code.
This issue has been fixed in Prettier 1.15.
// Input
let Subclass2 = class extends (Superclass as AssertedSuperclass) {};
// Output (Prettier 1.14)
let Subclass2 = class extends Superclass as AssertedSuperclass {};
// Output (Prettier 1.15)
let Subclass2 = class extends (Superclass as AssertedSuperclass) {};
Previously, necessary parens for optional types in tuple were wrongly removed, producing invalid code. This issue has been fixed in Prettier 1.15.
<!-- prettier-ignore -->// Input
type T = [("a" | "b")?];
// Output (Prettier 1.14)
type T = ["a" | "b"?];
// Output (Prettier 1.15)
type T = [("a" | "b")?];
/* prettier-ignore */ exist (#5103 by @ikatyang)In Prettier 1.14, location information in the AST were wrongly shifted
due to how we extract front matters from the source,
which led to /* prettier-ignore */ producing invalid output.
We've fixed this issue in Prettier 1.15.
/* Input */
---
hello: world
---
/* prettier-ignore */
.foo {}
/* Output (Prettier 1.14) */
---
hello: world
---
/* prettier-ignore */
pretti
/* Output (Prettier 1.15) */
---
hello: world
---
/* prettier-ignore */
.foo {}
Interpolations in CSS-in-JS templates could be anything, so we keep newlines for them in Prettier 1.15.
<!-- prettier-ignore -->// Input
const foo = styled.div`
${secondary}
flex: 0 0 auto;
`;
// Output (Prettier 1.14)
const foo = styled.div`
${secondary} flex: 0 0 auto;
`;
// Output (Prettier 1.15)
const foo = styled.div`
${secondary}
flex: 0 0 auto;
`;
Previously, we only detected front matters which did not use trailing spaces for their delimiters,
which led to an issue where thematic breaks (i.e., ---) were wrongly recognized as the end of the front matter.
We've fixed this issue by allowing trailing spaces for front matters' delimiters in Prettier 1.15,
which is also the way how GitHub processes front matters.
(· represents a whitespace)
<!-- Input -->
---
Title: Title
---···
__strong__ **strong**
---
<!-- Output (Prettier 1.14) -->
---
Title: Title
---···
__strong__ **strong**
---
<!-- Output (Prettier 1.15) -->
---
Title: Title
---···
**strong** **strong**
---
Previously, we always inserted whitespace between Latin and CJK characters to improve readability, but according to feedback we received, Korean uses conventional spaces, and inserting whitespaces would cause issues for them, so we disabled this behavior for Hangul in Prettier 1.15. Behavior is not changing for Chinese or Japanese.
<!-- prettier-ignore --><!-- Input -->
예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문
<!-- Output (Prettier 1.14) -->
예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문
<!-- Output (Prettier 1.15) -->
예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문
In Prettier 1.14, leading and trailing newlines are removed in fenced code block, which causes other plugins (e.g., php) to fail to format these code blocks. Leading and trailing newlines are preserved in Prettier 1.15.
<!-- prettier-ignore --><!-- Input -->
```
hello
```
<!-- Output (Prettier 1.14) -->
```
hello
```
<!-- Output (Prettier 1.15) -->
```
hello
```
Previously, anything that did not fit within the print width in a footnote definition was broken into multiple lines, but breaking a single line paragraph out onto its own was not much of a readability improvement, so we always inline them in Prettier 1.15.
<!-- prettier-ignore --><!-- Input -->
[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.
<!-- Output (Prettier 1.14) -->
[^1]:
In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.
<!-- Output (Prettier 1.15) -->
[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.
In Prettier 1.14, lists in front of whitespace-only trailing newlines are wrongly recognized as loose lists. This caused an issue where the user would need to format their code twice to get it stable, but when the code stabilized, it would produce the wrong output. This issue has been fixed in Prettier 1.15.
<!-- prettier-ignore -->// Input
if (condition) {
md`
- 123
- 456
`;
}
// First Output (Prettier 1.14)
if (condition) {
md`
- 123
- 456
`;
}
// Second Output (Prettier 1.14)
if (condition) {
md`
- 123
- 456
`;
}
// First & Second Output (Prettier 1.15)
if (true) {
md`
- 123
- 456
`;
}
Previously, string with escaped quotes in doubleQuote would cause invalid output. They're now correctly escaped in Prettier 1.15.
<!-- prettier-ignore --># Input
"'a\"b"
# Output (Prettier 1.14)
''a"b'
# Output (Prettier 1.15)
'''a"b'
In Prettier 1.14, there were some situations where trailing comments for document and document head may be moved. In Prettier 1.15, they're now always preserved.
<!-- prettier-ignore --># Input
--- # hello
... # world
# Output (Prettier 1.14)
# hello
# world
# Output (Prettier 1.15)
--- # hello
... # world
Previously, long flow mapping values were wrongly recognized as keys, which produced syntax errors since implicit keys with more than 1024 characters are not allowed. This issue has been fixed in Prettier 1.15.
(long represents a long text that is more than 1024 characters)
# Input
{x: long}
# Output (Prettier 1.14)
SyntaxError: The "undefine...ndefined" key is too long
# Output (Prettier 1.15)
{
x: long
}
Previously, a mapping item with an empty value was always printed with an explicit key, which is not that common and this confused people. In Prettier 1.15, we always print it with an implicit key in that situations.
<!-- prettier-ignore --># Input
a:
b:
# Output (Prettier 1.14)
a:
? b
# Output (Prettier 1.15)
a:
b:
Thanks to everyone who contributed to this release, as well as those who raised issues and gave us feedback. Prettier is a community-driven project and is only able to continue to exist thanks to people like you. Thank you!
Special thanks to @j-f1, @suchipi and @existentialism for reviewing this blog post!