Prettier 1.15: HTML, Vue, Angular and MDX Support
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.
Highlights
HTML/Vue/Angular
#5259 by @ikatyang, #4753 by @evilebottnawi, #2083 by @azz)
Support HTML, Vue, and Angular (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:
Whitespace-sensitive formatting
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 2 3 |
without spaces | 1<b>2</b>3 | 123 |
This happens because whitespace is significant in inline elements.
For this reason, we cannot safely format
<a href="https://prettier.io/">Prettier is an opinionated code formatter.</a>
into
<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:
- follows the default CSS
display
value for every element to identify if the whitespace inside it is significant, - and wraps the tags in such a way as to avoid adding or removing significant whitespace.
For example:
<!-- <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 CSSdisplay
property.strict
- All whitespace is considered significant.ignore
- All whitespace is considered insignificant.
Automatic parser inference
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 vue
Make 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
.
HTML template literal in JavaScript
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>
`;
Vue formatting
The following Vue-specific syntax structures are supported:
- interpolation
{{ something }}
- attribute
v-something
:something
@something
v-for
slot-scope
Angular formatting
The following Angular-specific syntax structures are supported:
- interpolation
{{ something }}
- attribute
(something)
[something]
[(something)]
*something
- inline template
@Component({ template: `<div>Hello World</div>` })
MDX
#4975 by @ikatyang)
Support MDX (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!
<!-- 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} />
JavaScript
#5039 by @suchipi, #5272 by @duailibe, #5333 by @ikatyang)
Flatten else-branch for nested ternaries (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;
#5188 by @duailibe)
Keep decorators inline if they were written inline (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.
// 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";
}
#5207 by @duailibe)
Respect original decorator order (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.)
// decorator before export
@decorator export class Bar {}
// decorator after export
export @decorator class Foo {}
#5205 by @j-f1)
Improved object-break heuristic (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' }
JSX
#4798 by @smirea)
Option to use single quotes in JSX (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>
#5006 by @yuliaHope)
Split JSX text correctly (Prettier 1.14 accidentally introduced some very unfortunate line breaks in JSX. Those cases have now been fixed.
// 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>;
Flow
#5304 by @jbrown215, #5356 by @existentialism)
Support inexact (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.
type T = {
a: number,
...
}
#5280, #5290 by @swac)
Do not break Flow typecast comments (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.
// Input
(obj /*: Class */).property
// Output (Prettier 1.14)
obj /*: Class */.property;
// Output (Prettier 1.15)
(obj /*: Class */).property;
Markdown
#5050, #5220 by @ikatyang)
Preserve math syntax (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.
$inline-math$
$$
block-math
$$
Other changes
API/CLI
#5149 by @haggholm)
Infer parser via shebang if there's no extension in the filename (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.
# Input
$ cat bin/example
#!/usr/bin/env node
require ( "../src/cli" ) . run ( )
$ prettier bin/example
# Output (Prettier 1.14)
[error] No parser could be inferred for file: bin/example
# Output (Prettier 1.15)
#!/usr/bin/env node
require("../src/cli").run();
trim
command to trim whitespaces in the current line (#4772 by @warrenseine)
Add a new 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.
#5020, #5057 by @ikatyang)
Colorful validation message (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.
# Input
$ prettier filename.js --trailing-comma wow
# Output (Prettier 1.14)
[error] Invalid ``--trailing-comma`` value. Expected "all", "es5" or "none", but received `"wow"`.
# Output (Prettier 1.15)
[error] Invalid --trailing-comma value. Expected "all", "es5" or "none", but received "wow".
#5041 by @ikatyang)
Allow printer to preprocess the AST (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;
}
#4969 by @ikatyang)
Better error message for unsupported config format (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.
# Input
$ prettier filename.js --config .prettierrc.wow
# Output (Prettier 1.14)
[error] Invalid configuration file: Cannot read property 'sync' of undefined
# Output (Prettier 1.15)
[error] Invalid configuration file: No sync loader specified for extension ".wow"
#5327 by @kachkaev)
Add an option to enforce line endings (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.
JavaScript
#5206 by @j-f1, #5330 by @lydell)
Treat single-star comments as JSDoc (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
*/
}
#5243 by @bakkot)
Correct parentheses for mixed exponentiation/modulo (Previously, parentheses for mixed exponentiation/modulo were wrongly removed, but we fixed this in Prettier 1.15.
// 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)
Correctly print comments in 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
}
#5202 by @duailibe)
Printing comments in catch clause to the correct place (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
) {}
#5209 by @duailibe)
Inline the argument if it's an arrow function with conditional expression as body (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.
// Input
x.then(() => a ?
veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong:
veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
// Output (Prettier 1.14)
x.then(
() =>
a
? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
: veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
// Output (Prettier 1.15)
x.then(() =>
a
? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
: veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);
#5190 by @duailibe)
Fix unexpected indentation in variable declarator caused by comments (In previous versions, comments in variable declarations caused variable declarators to be printed without indentation, but this has been fixed in Prettier 1.15.
// Input
const // Comment
a = 1;
// Output (Prettier 1.14)
const // Comment
a = 1;
// Output (Prettier 1.15)
const // Comment
a = 1;
#5179 by @existentialism)
Do not remove parens for ternary in optional member expression (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)
Escape 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.
// 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
}
`;
#5157 by @koba04)
Do not strip quotes in keys if they're not es5 compatible (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.
// Input
var obj = {
"𐊧": 'ok',
𐊧: 'ok'
};
// Output (Prettier 1.14)
var obj = {
𐊧: "ok",
𐊧: "ok"
};
// Output (Prettier 1.15)
var obj = {
"𐊧": "ok",
𐊧: "ok"
};
#5151 by @onurtemizkan)
Do not hug arguments if the second argument in function is a ternary (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.
// 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)
);
#5085 by @j-f1)
Add support for timeouts passed as numbers to test functions (This preserves Prettier’s special formatting for testing functions when a timeout (number) is passed as a third parameter:
// 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)
#5011 by @ericsakmar)
Format beforeEach-like calls like regular function calls (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())
);
#5015 by @flxwu)
Print pipeline operator's leading comment on its own line (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.
// 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)
Preserve dangling comments in 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 */);
#4970 by @TitanSnow)
Remove redundant ASI protection for bind expression (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
#4964 by @TitanSnow)
Do not remove necessary parens in bind expression (Necessary parens in bind expressions are preserved in Prettier 1.15.
// Input
a::(b.c());
// Output (Prettier 1.14)
a::b.c();
// Output (Prettier 1.15)
a::(b.c());
#4368 by @malcolmsgroves)
Fix indentation for ternary in function call (Logical expressions in a ternary in a function call are now indented correctly.
// 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
);
import
s (#5016 by @ericsakmar)
Do not move comments in Comments in import
s 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)
Fix unstable 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
) {}
#5250 by @jaideng123)
Stably print comments between function declaration and its body (Comments between a function declaration and its body do not need to be formatted twice to get the final result now.
// 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;
}
JSX
#5092 by @duailibe)
Do not break logical expression chain in JSX (Unnecessary indentations for logical expression chains in JSX are now prevented.
// 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>
)}
</>
);
};
#5165 by @vjeux, #5334 by @ikatyang)
Do not change non-breaking whitespace into the regular one (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>
);
}
#5078 by @duailibe)
Do not break simple jsx opening tag (Simple jsx opening tags are no longer broken onto multiple lines.
// 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>
}
/>
);
}
#5063 by @ikatyang)
Fix a regression for arrow function in jsx expression (// 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>;
Flow
#5066 by @duailibe)
Inline generics with a single identifier (Generics with a single identifier are now always inlined.
// 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)
Do not always inline classes in 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)
Do not add unnecessary parens for async function in 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() {}
TypeScript
#5262 by @duailibe)
Add ASI protection for non-null assertion (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)
Do not add extra semicolon for method signature when Extra semicolon for method signature is removed in Prettier 1.15.
// 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;
}
#5096 by @ikatyang)
Do not print invalid parens for destructuring with default value (Previously, Prettier printed invalid parens for destructuring with default value, we fixed this issue in Prettier 1.15.
// 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)
Do not print semicolon for class properties with modifiers in 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.
// 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)
Do not remove parens for complex nodes in ClassExpression's 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) {};
#5056 by @ikatyang)
Do not remove necessary parens for TSOptionalType (Previously, necessary parens for optional types in tuple were wrongly removed, producing invalid code. This issue has been fixed in Prettier 1.15.
// Input
type T = [("a" | "b")?];
// Output (Prettier 1.14)
type T = ["a" | "b"?];
// Output (Prettier 1.15)
type T = [("a" | "b")?];
CSS
/* prettier-ignore */
exist (#5103 by @ikatyang)
Do not print wrong output if both front matter and 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 {}
#5240 by @onurtemizkan)
Keep newlines in CSS-in-JS Templates (Interpolations in CSS-in-JS templates could be anything, so we keep newlines for them in Prettier 1.15.
// 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;
`;
Markdown
#5107 by @ikatyang)
Trailing spaces for front matters' delimiters are allowed (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**
---
#5040 by @ikatyang)
Do not add whitespaces between Latin and Hangul (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.
<!-- 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 예문
#5038 by @ikatyang)
Preserve leading and trailing newlines in fenced code block (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.
<!-- Input -->
```
hello
```
<!-- Output (Prettier 1.14) -->
```
hello
```
<!-- Output (Prettier 1.15) -->
```
hello
```
#5025 by @ikatyang)
Inline footnote definition if there's only a single line paragraph (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.
<!-- 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.
#5024 by @ikatyang)
Correctly print lists in front of whitespace-only trailing newlines (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.
// 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
`;
}
YAML
#5236 by @ikatyang)
Escape quotes correctly (Previously, string with escaped quotes in doubleQuote would cause invalid output. They're now correctly escaped in Prettier 1.15.
# Input
"'a\"b"
# Output (Prettier 1.14)
''a"b'
# Output (Prettier 1.15)
'''a"b'
#5027 by @ikatyang)
Preserve trailing comments for document and document head (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.
# Input
--- # hello
... # world
# Output (Prettier 1.14)
# hello
# world
# Output (Prettier 1.15)
--- # hello
... # world
#5027 by @ikatyang)
Do not throw error for flow mapping item with long value (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
}
#4972 by @ikatyang)
Prefer implicit key for empty mapping value (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.
# Input
a:
b:
# Output (Prettier 1.14)
a:
? b
# Output (Prettier 1.15)
a:
b:
Thanks! ❤️
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!