Skip to main content

Prettier 1.19: Long awaited Vue option, TypeScript 3.7 and new JavaScript features

· 27 min read

This release adds the long awaited --vue-indent-script-and-style option, support for TypeScript 3.7 and some cutting edge JavaScript syntax. Not to mention a whole bunch of bug fixes and improvements!

Highlights

Vue

Add --vue-indent-script-and-style (#6157 by @kamilic)

The new --vue-indent-script-and-style option controls whether or not to indent the code inside <script> and <style> tags in Vue files. Some people (like the creator of Vue) don’t indent to save an indentation level, but this might break code folding in your editor. This closes our most commented issue so far, and should improve lots of Vue coders’ editing experience!

TypeScript

Support for TypeScript 3.7 (#6657 by @cryrivers)

Prettier 1.19 adds support for the features of the upcoming TypeScript 3.7 that introduce new syntax:

(Note: A dependency upgrade for TypeScript 3.7 led to dropping Node.js 6 support for direct installation from GitHub. Prettier installed from npm stays compatible with Node.js 4.)

Optional Chaining
// Input
const longChain = obj?.a?.b?.c?.d?.e?.f?.g;
const longChainCallExpression = obj.a?.(a,b,c).b?.(a,b,c).c?.(a,b,c).d?.(a,b,c).e?.(a,b,c).f?.(a,b,c)

// Prettier 1.19
const longChain = obj?.a?.b?.c?.d?.e?.f?.g;
const longChainCallExpression = obj
.a?.(a, b, c)
.b?.(a, b, c)
.c?.(a, b, c)
.d?.(a, b, c)
.e?.(a, b, c)
.f?.(a, b, c);
Nullish Coalescing
// Input
const cond = null;
const result = cond??'a';
const longChain = cond??cond??cond??'b';

// Prettier 1.19
const cond = null;
const result = cond ?? "a";
const longChain = cond ?? cond ?? cond ?? "b";
Assertion Functions
// Input
function assertsString(x: any): asserts x {console.assert(typeof x === 'string');}
function assertsStringWithGuard(x: any): asserts x is string {console.assert(typeof x === 'string');}

// Prettier 1.19
function assertsString(x: any): asserts x {
console.assert(typeof x === "string");
}
function assertsStringWithGuard(x: any): asserts x is string {
console.assert(typeof x === "string");
}
declare Modifier on Class Fields
// Input
class B {p: number;}
class C extends B {declare p: 256 | 1000;}

// Prettier 1.19
class B {
p: number;
}
class C extends B {
declare p: 256 | 1000;
}

JavaScript

Add support for partial application syntax (#6397 by @JounQin)

// Input
const addOne = add(1, ?); // apply from the left
addOne(2); // 3

const addTen = add(?, 10); // apply from the right
addTen(2); // 12

// with pipeline
let newScore = player.score
|> add(7, ?)
|> clamp(0, 100, ?); // shallow stack, the pipe to `clamp` is the same frame as the pipe to `add`.

// Prettier 1.18
SyntaxError: Unexpected token (1:23)
> 1 | const addOne = add(1, ?); // apply from the left
| ^
2 | addOne(2); // 3
3 |
4 | const addTen = add(?, 10); // apply from the right

// Prettier 1.19
const addOne = add(1, ?); // apply from the left
addOne(2); // 3

const addTen = add(?, 10); // apply from the right
addTen(2); // 12

// with pipeline
let newScore = player.score |> add(7, ?) |> clamp(0, 100, ?); // shallow stack, the pipe to \`clamp\` is the same frame as the pipe to \`add\`.

Use function literals in arguments to detect function composition (#6033 by @brainkim)

Previously, we used a set of hard-coded names related to functional programming (compose, flow, pipe, etc.) to detect function composition and chaining patterns in code. This was done so that Prettier would not put code like the following call to pipe on the same line even if it fit within the allotted column budget:

source$
.pipe(
filter(x => x % 2 === 0),
map(x => x + x),
scan((acc, x) => acc + x, 0),
)
.subscribe(x => console.log(x));

However, this heuristic caused people to complain because of false positives where calls to functions or methods matching the hard-coded names would always be split on multiple lines, even if the calls did not contain function arguments (#5769, #5969). For many, this blanket decision to split functions based on name was both surprising and sub-optimal.

We now use a refined heuristic which uses the presence of function literals to detect function composition. This heuristic preserves the line-splitting behavior above and eliminates many if not all of the false positives caused by the older heuristic.

Try it out and feel free to provide feedback!

// Input
eventStore.update(id, _.flow(updater, incrementVersion));

// Prettier 1.18
eventStore.update(
id,
_.flow(
updater,
incrementVersion
)
);

// Prettier 1.19
eventStore.update(id, _.flow(updater, incrementVersion));

Enable formatting even if there are parse errors in some cases (#6816 by @thorn0 and the Babel team)

We updated the Babel parser to the latest version and got an awesome feature for free. Prettier is now able to format your code even if it is invalid in some cases, which should make your coding experience smoother. This will get better over time as Babel improves their error recovery parsing mode. Read more in the Babel 7.7.0 blog post!

// Input
let a = {
__proto__ : x,
__proto__ : y
}
let a = 2

// Prettier 1.18
SyntaxError: Redefinition of __proto__ property (3:3)
1 | let a = {
2 | __proto__ : x,
> 3 | __proto__ : y
| ^
4 | }
5 | let a = 2

// Prettier 1.19
let a = {
__proto__: x,
__proto__: y
};
let a = 2;

Other changes

TypeScript

Fix optional computed class fields and methods (#6657 by @cryrivers, #6673 by @thorn0)

This is still broken if the key is a complex expression, but it has been fixed in these cases:

// Input
class Foo {
[bar]?: number;
protected [s]?() {}
}

// Prettier 1.18
class Foo {
[bar]: number;
protected [s?]() {};
}

// Prettier 1.19
class Foo {
[bar]?: number;
protected [s]?() {}
}

Comments after JSX element names with type arguments were lost (#6209 by @duailibe)

// Input
const comp = (
<Foo<number>
// This comment goes missing
value={4}
>
Test
</Foo>
);

// Prettier 1.18
const comp = <Foo<number> value={4}>Test</Foo>;

// Prettier 1.19
const comp = (
<Foo<number>
// This comment goes missing
value={4}
>
Test
</Foo>
);

Fix crashes when using // in JSX texts (#6289 by @duailibe)

This version updates the TypeScript parser to correctly handle JSX text with double slashes (//). In previous versions, this would cause Prettier to crash.

Correctly format long one-line mapped types in one pass (#6420 by @sosukesuzuki)

Previously, when Prettier formatted long one-line mapped types, it would break the line but didn’t add a semicolon until you ran Prettier again, which means Prettier’s idempotence rule was broken. Now, Prettier adds the semicolon in the first run.

// Input
type FooBar<T> = { [P in keyof T]: T[P] extends Something ? Something<T[P]> : T[P] }

// Prettier 1.18
type FooBar<T> = {
[P in keyof T]: T[P] extends Something ? Something<T[P]> : T[P]
};

// Prettier 1.19
type FooBar<T> = {
[P in keyof T]: T[P] extends Something ? Something<T[P]> : T[P];
};

Keep type parameters inline for type annotations in variable declarations (#6467 by @sosukesuzuki)

// Input
const fooooooooooooooo: SomeThing<boolean> = looooooooooooooooooooooooooooooongNameFunc();

// Prettier 1.18
const fooooooooooooooo: SomeThing<
boolean
> = looooooooooooooooooooooooooooooongNameFunc();

// Prettier 1.19
const fooooooooooooooo: SomeThing<boolean> = looooooooooooooooooooooooooooooongNameFunc();

Sometimes double parentheses around types were removed incorrectly (#6604 by @sosukesuzuki)

// Input
type A = 0 extends ((1 extends 2 ? 3 : 4)) ? 5 : 6;
type B = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6;
type C = ((number | string))["toString"];
type D = ((keyof T1))["foo"];

// Prettier 1.18
type A = 0 extends 1 extends 2 ? 3 : 4 ? 5 : 6;
type B = 0 extends 1 ? 2 : 3 extends 4 ? 5 : 6;
type C = number | string["toString"];
type D = keyof T1["foo"];

// Prettier 1.19
type A = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6;
type B = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6;
type C = (number | string)["toString"];
type D = (keyof T1)["foo"];

Keep parentheses around JSX when needed to avoid syntax errors (#6640 by @sosukesuzuki)

// Input
(<a />).toString();

// Prettier 1.18
<a />.toString():

// Prettier 1.19
(<a />).toString();

Keep semi for a class property before index signature when no-semi is enabled (#6728 by @sosukesuzuki)

Attempting to format Prettier’s output again used to result in a syntax error.

// Input
export class User {
id: number = 2;
[key: string]: any
}

// Prettier 1.18
export class User {
id: number = 2
[key: string]: any
}

// Prettier 1.19
export class User {
id: number = 2;
[key: string]: any
}

Improve argument expansion with as type expressions (#6471 by @mattleff)

Previously, when Prettier formatted a call expression containing an as type expression or a type assertion, it would break the line. Now, Prettier uses the expression contained by the as type or type assertion to determine line breaks.

// Input
const bar = [1,2,3].reduce((carry, value) => {
return [...carry, value];
}, ([] as unknown) as number[]);

// Prettier 1.18
const bar = [1, 2, 3].reduce(
(carry, value) => {
return [...carry, value];
},
([] as unknown) as number[]
);

// Prettier 1.19
const bar = [1,2,3].reduce((carry, value) => {
return [...carry, value];
}, ([] as unknown) as number[]);

TypeScript/Flow

Fix indentation for union types inside tuples (#6381 by @squidfunk, #6605 by @thorn0)

// Input
type A = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]

type B = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD,
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]

type C = [
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
]

// Prettier 1.18
type A = [

| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
];

type B = [

| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD,

| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
];

type C = [

| [

| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]
| [

| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]
];

// Prettier 1.19
type A = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
];

type B = [
(
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
),
(
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
)
];

type C = [
| [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]
| [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]
];

Fix moving comments in function calls like useEffect (#6270 by @sosukesuzuki)

This fixes a bug that was affecting function calls with an arrow function as the first argument and an array expression as the second argument, e.g. React's useEffect. If a comment was placed on the line before the second argument, Prettier would move it to the line above and corrupt the indentation.

The bug was only present when using the Flow and TypeScript parsers.

// Input
useEffect(
() => {
console.log("some code", props.foo);
},

// eslint-disable-line react-hooks/exhaustive-deps
[]
);

// Prettier 1.18
useEffect(() => {
console.log("some code", props.foo);
}, // eslint-disable-line react-hooks/exhaustive-deps
[]);

// Prettier 1.19
useEffect(
() => {
console.log("some code", props.foo);
},

// eslint-disable-line react-hooks/exhaustive-deps
[]
);

Put a closing parenthesis onto a new line after union types (#6307 by @sosukesuzuki)

// Input
const foo = [abc, def, ghi, jkl, mno, pqr, stu, vwx, yz] as (
| string
| undefined
)[];

// Prettier 1.18
const foo = [abc, def, ghi, jkl, mno, pqr, stu, vwx, yz] as (
| string
| undefined)[];

// Prettier 1.19
const foo = [abc, def, ghi, jkl, mno, pqr, stu, vwx, yz] as (
| string
| undefined
)[];

Flow

Add support for enums (#6833 by @gkz)

// Input
enum E of string {
A = "a", B = "b"
}

// Prettier 1.19
enum E of string {
A = "a",
B = "b",
}

Parentheses around arrow functions' return types that have FunctionTypeAnnotation nested in ObjectTypeAnnotation (#6717 by @sosukesuzuki)

This is a workaround for a bug in the Flow parser. Without the parentheses, the parser throws an error.

// Input
const example1 = (): { p: (string => string) } => (0: any);

// Prettier 1.18
const example1 = (): { p: string => string } => (0: any);

// Prettier 1.19
const example1 = (): ({ p: string => string }) => (0: any);

JavaScript

Break arrays of arrays/objects if each element has more than one element/property (#6694 by @sosukesuzuki)

This should format your new Map and Jest test.each calls more nicely.

// Input
test.each([
{ a: "1", b: 1 },
{ a: "2", b: 2 },
{ a: "3", b: 3 }
])("test", ({ a, b }) => {
expect(Number(a)).toBe(b);
});
[[0, 1, 2], [0, 1, 2]];
new Map([
[A, B],
[C, D],
[E, F],
[G, H],
[I, J],
[K, L],
[M, N]
]);

// Prettier 1.18
test.each([{ a: "1", b: 1 }, { a: "2", b: 2 }, { a: "3", b: 3 }])(
"test",
({ a, b }) => {
expect(Number(a)).toBe(b);
}
);
[[0, 1, 2], [0, 1, 2]]
new Map([[A, B], [C, D], [E, F], [G, H], [I, J], [K, L], [M, N]]);

// Prettier 1.19
test.each([
{ a: "1", b: 1 },
{ a: "2", b: 2 },
{ a: "3", b: 3 }
])("test", ({ a, b }) => {
expect(Number(a)).toBe(b);
});
[
[0, 1, 2],
[0, 1, 2]
];
new Map([
[A, B],
[C, D],
[E, F],
[G, H],
[I, J],
[K, L],
[M, N]
]);

Update ?? precedence to match stage 3 proposal (#6404 by @vjeux, #6863 by @jridgewell)

We've updated Prettier's support for the nullish coalescing operator to match a spec update that no longer allows it to immediately contain, or be contained within an && or || operation.

// Input
(foo ?? bar) || baz;
(foo || bar) ?? baz;

// Prettier 1.18
foo ?? bar || baz;
foo || bar ?? baz;

// Prettier 1.19
(foo ?? bar) || baz;
(foo || bar) ?? baz;

Please note that since we have updated our parsers with versions that support this spec update, code without the parentheses will throw a parse error.

Don't require parens for same-operator logical expressions (#6864 by @jridgewell)

// Input
foo && (bar && baz);
foo || (bar || baz);
foo ?? (bar ?? baz);

// Prettier 1.18
foo && (bar && baz);
foo || (bar || baz);
foo ?? (bar ?? baz);

// Prettier 1.19
foo && bar && baz;
foo || bar || baz;
foo ?? bar ?? baz;

More readable parentheses for new call (#6412 by @bakkot)

// Input
var a = new (x().y)();
var a = new (x().y.z)();
var a = new (x().y().z)();

// Prettier 1.18
var a = new (x()).y();
var a = new (x()).y.z();
var a = new (x().y()).z();

// Prettier 1.19
var a = new (x().y)();
var a = new (x().y.z)();
var a = new (x().y().z)();

Keep parentheses with comments in unary expressions (#6217 by @sosukesuzuki)

// Input
!(
/* foo */
foo
);
!(
foo // foo
);

// Prettier 1.18
!/* foo */
foo;
!foo; // foo

// Prettier 1.19
!(/* foo */ foo);
!(
foo // foo
);

Stop moving comments inside tagged template literals (#6236 by @sosukesuzuki)

// Input
foo //comment
`
`;

// Prettier 1.18
foo` // comment
`;

// Prettier 1.19
foo // comment
`
`;

Empty lines in destructured arrow function parameters could break indentation and idempotence (#6301 & #6382 by @sosukesuzuki)

Previously, Prettier indented code strangely when an arrow function whose parameters included an object pattern was passed to a function call as an argument. Also, it broke idempotence. Please see #6294 for details.

// Input
foo(
({
a,

b
}) => {}
);

// Prettier 1.18
foo(({ a,
b }) => {});

// Prettier 1.19
foo(
({
a,

b
}) => {}
);

Fix formatting of object destructuring with parameter decorators (#6411 by @sosukesuzuki)

// Input
class Class {
method(
@decorator
{ foo }
) {}
}

// Prettier 1.18
class Class {
method(@decorator
{
foo
}) {}
}

// Prettier 1.19
class Class {
method(
@decorator
{ foo }
) {}
}

Handle empty object patterns with type annotations in function parameters (#6438 by @bakkot)

// Input
const f = ({}: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {};
function g({}: Foo) {}

// Prettier 1.18
const f = ({
,
}: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {};
function g({ }: Foo) {}

// Prettier 1.19
const f = ({}: MyVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongType) => {};
function g({}: Foo) {}

Put a closing parenthesis onto a new line after binary expressions within function calls (#6441 by @sosukesuzuki)

// Input
(
aaaaaaaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbb &&
ccccccccccccccccccccccccc &&
ddddddddddddddddddddddddd &&
eeeeeeeeeeeeeeeeeeeeeeeee
)();

// Prettier 1.18
(aaaaaaaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbb &&
ccccccccccccccccccccccccc &&
ddddddddddddddddddddddddd &&
eeeeeeeeeeeeeeeeeeeeeeeee)();

// Prettier 1.19
(
aaaaaaaaaaaaaaaaaaaaaaaaa &&
bbbbbbbbbbbbbbbbbbbbbbbbb &&
ccccccccccccccccccccccccc &&
ddddddddddddddddddddddddd &&
eeeeeeeeeeeeeeeeeeeeeeeee
)();

Fix formatting of long named exports (#6446 by @sosukesuzuki)

Now, Prettier formats named exports the same way as named imports.

// Input
export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo";

// Prettier 1.18
export {
fooooooooooooooooooooooooooooooooooooooooooooooooo
} from "fooooooooooooooooooooooooooooo";

// Prettier 1.19
export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo";

Fix bad formatting for multi-line optional chaining with comment (#6506 by @sosukesuzuki)

// Input
return a
.b()
.c()
// Comment
?.d()

// Prettier 1.18
return a
.b()
.c()
?.// Comment
d();

// Prettier 1.19
return (
a
.b()
.c()
// Comment
?.d()
);

Fix inconsistent indentation in switch statement (#6514 by @sosukesuzuki)

// Input
switch ($veryLongAndVeryVerboseVariableName && $anotherVeryLongAndVeryVerboseVariableName) {
}

switch ($longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName) {
}

// Prettier 1.18
switch (
$veryLongAndVeryVerboseVariableName &&
$anotherVeryLongAndVeryVerboseVariableName
) {
}

switch (
$longButSlightlyShorterVariableName && $anotherSlightlyShorterVariableName
) {
}

// Prettier 1.19
switch (
$veryLongAndVeryVerboseVariableName &&
$anotherVeryLongAndVeryVerboseVariableName
) {
}

switch (
$longButSlightlyShorterVariableName &&
$anotherSlightlyShorterVariableName
) {
}

Support formatting code with V8 intrinsics (#6496 by @rreverser)

// Input
function doSmth() {
%DebugPrint
(
foo )
}

// Prettier 1.18
SyntaxError: Unexpected token (2:13)
1 | function doSmth() {
> 2 | %DebugPrint
| ^

// Prettier 1.19
function doSmth() {
%DebugPrint(foo);
}

Object destructuring in method parameters always broke into multiple lines (#6646 by @ericsakmar)

// Input
const obj = {
func(id, { blog: { title } }) {
return id + title;
},
};

class A {
func(id, { blog: { title } }) {
return id + title;
}
#func(id, { blog: { title } }) {
return id + title;
}
}

// Prettier 1.18
const obj = {
func(
id,
{
blog: { title }
}
) {
return id + title;
}
};

class A {
func(
id,
{
blog: { title }
}
) {
return id + title;
}
#func(
id,
{
blog: { title }
}
) {
return id + title;
}
}

// Prettier 1.19
const obj = {
func(id, { blog: { title } }) {
return id + title;
},
};

class A {
func(id, { blog: { title } }) {
return id + title;
}
#func(id, { blog: { title } }) {
return id + title;
}
}

Numeric separators were removed from BigInt literals (#6796 by @thorn0)

// Input
const bigints = [200_000n, 0x0000_000An, 0b0111_1111n];

// Prettier 1.18
const bigints = [200000n, 0x0000000an, 0b01111111n];

// Prettier 1.19
const bigints = [200_000n, 0x0000_000an, 0b0111_1111n];

Better formatting for inline await expression nested in calls (#6856 by @thorn0)

// Input
async function f() {
const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name}))
}

// Prettier 1.18
async function f() {
const admins = (await db
.select("*")
.from("admins")
.leftJoin("bla")
.where("id", "in", [1, 2, 3, 4])).map(({ id, name }) => ({ id, name }));
}

// Prettier 1.19
async function f() {
const admins = (
await db
.select("*")
.from("admins")
.leftJoin("bla")
.where("id", "in", [1, 2, 3, 4])
).map(({ id, name }) => ({ id, name }));
}

HTML

Don't wrap template elements on lines shorter than printWidth (#6284 by @sosukesuzuki)

Previously, even if the line length was shorter than printWidth, Prettier would break the line with a template element.

<!-- Input -->
<template>
<template>foo</template>
</template>

<!-- Prettier 1.18 -->
<template>
<template
>foo</template
>
</template>

<!-- Prettier 1.19 -->
<template>
<template>foo</template>
</template>

Script tags are now treated as blocks for the purposes of formatting (#6423 by @thorn0)

Previously, in the whitespace-sensitive mode, they were formatted as if they were inline.

<!-- Input -->
<script
async
src="/_next/static/development/pages/_app.js?ts=1565732195968"
></script><script></script>

<!-- Prettier 1.18 -->
<script
async
src="/_next/static/development/pages/_app.js?ts=1565732195968"
></script
><script></script>

<!-- Prettier 1.19 -->
<script
async
src="/_next/static/development/pages/_app.js?ts=1565732195968"
></script>
<script></script>

Add support for &excl; and other entities (#6785 by @lydell and @ikatyang)

Previously, Prettier only supported the most common HTML entities, such as &nbsp; and &quot;. Now, Prettier supports every HTML entity in the HTML spec, such as &excl; and &pitchfork;.

<!-- Input -->
<p>Hi&excl;</p>

<!-- Prettier 1.18
[error] stdin: SyntaxError: Unknown entity "excl" - use the "&#<decimal>;" or "&#x<hex>;" syntax (1:6)
[error] > 1 | <p>Hi&excl;</p>
[error] | ^
[error] 2 |
-->

<!-- Prettier 1.19 -->
<p>Hi&excl;</p>

Add JSON script types (#6293 by @ascorbic)

<!-- Input -->
<script type="application/json">
{ "json":true }
</script>
<script type="importmap">
{ "json":true }
{ "json":true }
</script>
</script>
<script type="systemjs-importmap">
{ "json":true }
</script>

<!-- Prettier 1.18 -->
<script type="application/json">
{ "json":true }
</script>
<script type="importmap">
{ "json":true }
{ "json":true }
</script>
</script>
<script type="systemjs-importmap">
{ "json":true }
</script>

<!-- Prettier 1.19 -->
<script type="application/json">
{ "json": true }
</script>
<script type="importmap">
{ "json": true }
</script>
<script type="systemjs-importmap">
{ "json": true }
</script>

Angular

Put a closing parenthesis onto a new line after ternaries passed to pipes (#5682 by @selvazhagan)

<!-- Input -->
{{ (isCustomDiscount ? 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT' : 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT') | translate }}

<!-- Prettier 1.18 -->
{{
(isCustomDiscount
? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT"
: "DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT") | translate
}}

<!-- Prettier 1.19 -->
{{
(isCustomDiscount
? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT"
: "DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT"
) | translate
}}

Add formatting for i18n attributes (#6695 by @voithos)

Prettier will auto-wrap the contents of i18n attributes once they exceed the line length.

<!-- Input -->
<h1 i18n="This is a very long internationalization description text, exceeding the configured print width">
Hello!
</h1>

<!-- Prettier 1.18 -->
<h1
i18n="This is a very long internationalization description text, exceeding the configured print width"
>
Hello!
</h1>

<!-- Prettier 1.19 -->
<h1
i18n="
This is a very long internationalization description text, exceeding the
configured print width
"
>
Hello!
</h1>

Handlebars

Fix handling of whitespace and line breaks (#6354 by @chadian)

This fixes a variety of whitespace and line break use cases within Handlebars and Glimmer templates.

<!-- Input -->
<SomeComponent />{{name}}

Some sentence with {{dynamic}} expressions.



sometimes{{nogaps}}areimportant<Hello></Hello>
{{name}} is your name

<!-- Prettier 1.18 -->
<SomeComponent />
{{name}}
Some sentence with
{{dynamic}}
expressions.



sometimes
{{nogaps}}
areimportant
<Hello />
{{name}}
is your name

<!-- Prettier 1.19 -->
<SomeComponent />{{name}}

Some sentence with {{dynamic}} expressions.



sometimes{{nogaps}}areimportant
<Hello />
{{name}} is your name

Avoid adding unwanted line breaks between text and mustaches (#6186 by @gavinjoyce)

Previously, Prettier added line breaks between text and mustaches which resulted in unwanted whitespace in rendered output.

<!-- Input -->
<p>Your username is @{{name}}</p>
<p>Hi {{firstName}} {{lastName}}</p>

<!-- Prettier 1.18 -->
<p>
Your username is @
{{name}}
</p>
<p>
Hi
{{firstName}}
{{lastName}}
</p>

<!-- Prettier 1.19 -->
<p>
Your username is @{{name}}
</p>
<p>
Hi {{firstName}} {{lastName}}
</p>

Improve comment formatting (#6206 by @gavinjoyce)

<!-- Input -->
<div>
{{! Foo }}
{{#if @foo}}
Foo
{{/if}}

{{! Bar }}
{{#if @bar}}
Bar
{{/if}}
</div>

<!-- Prettier 1.18 -->
<div>
{{! Foo }}
{{#if @foo}}
Foo
{{/if}}{{! Bar }}{{#if @bar}}
Bar
{{/if}}
</div>

<!-- Prettier 1.19 -->
<div>
{{! Foo }}
{{#if @foo}}
Foo
{{/if}}
{{! Bar }}
{{#if @bar}}
Bar
{{/if}}
</div>

Preserve HTML entities (#6234 by @gavinjoyce)

<!-- Input -->
<p>
Some escaped characters: &lt; &gt; &amp;
</p>

<!-- Prettier 1.18 -->
<p>
Some escaped characters: < > &
</p>

<!-- Prettier 1.19 -->
<p>
Some escaped characters: &lt; &gt; &amp;
</p>

Fix --single-quote option on HTML attributes (#6377 by @dcyriller)

Previously, the flag was not applied on HTML attributes.

<!-- Input -->
<div class="a-class-name"></div>

<!-- Prettier 1.18, with the option --single-quote -->
<div class="a-class-name"></div>

<!-- Prettier 1.19, with the option --single-quote -->
<div class='a-class-name'></div>

Break long interpolations (#6249 by @jjaffeux)

<!-- Input -->
{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx")
}}

<!-- Prettier 1.18 -->
{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx")
}}

<!-- Prettier 1.19 -->
{{my-component
foo="bar"
bar="baz"
action=(action "almostTheMaximumLengthxxxx")
}}

MDX

Text following JSX was trimmed incorrectly (#6340 by @JounQin)

<!-- Input -->
<Hello>
test <World /> test
</Hello> 123

<!-- Prettier 1.18 -->
<Hello>
test <World /> test
</Hello>123

<!-- Prettier 1.19 -->
<Hello>
test <World /> test
</Hello> 123

Adjacent JSX elements should be allowed (#6332 by @JounQin)

// Input
<Hello>
test <World /> test
</Hello>123

// Prettier 1.18
SyntaxError: Unexpected token (3:9)
1 | <Hello>
2 | test <World /> test
> 3 | </Hello>123
| ^

// Prettier 1.19
<Hello>
test <World /> test
</Hello>123


// Input
<Hello>
test <World /> test
</Hello>
<Hello>
test <World /> test
</Hello>123

// Prettier 1.18
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (4:1)
2 | test <World /> test
3 | </Hello>
> 4 | <Hello>
| ^
5 | test <World /> test
6 | </Hello>123

// Prettier 1.19
<Hello>
test <World /> test
</Hello>
<Hello>
test <World /> test
</Hello>123

Vue

Format style[lang="css"] (#6875 by @fisker)

Previously, <style> elements with lang="css" were not formatted, while omitting the attribute or setting to some other values worked. This oversight has been fixed.

<!-- Input -->
<style lang="css">
a {
color: #F00
}</style>

<!-- Output (Prettier stable) -->
<style lang="css">
a {
color: #F00
}
</style>

<!-- Output (Prettier master) -->
<style lang="css">
a {
color: #f00;
}
</style>

Less

Don't lowercase variable names and remove whitespace between variable and colon (#6778 by @fisker)

// Input
@FoO : bar;

// Prettier 1.18
@foo : bar;

// Prettier 1.19
@FoO: bar;

API

Add resolveConfig option to getFileInfo() (#6666 by @kaicataldo)

Add a resolveConfig: boolean option to prettier.getFileInfo() that, when set to true, will resolve the configuration for the given file path. This allows consumers to take any overridden parsers into account.

CLI

Handle errors when reading stdin (#6708 by @andersk and @lydell)

If you had an error in your .prettierrc Prettier used to crash when formatting stdin. Such errors are now handled properly.

# Prettier 1.18
$ prettier --parser babel < test.js
(node:21531) UnhandledPromiseRejectionWarning: Error: Invalid printWidth value. Expected an integer, but received "nope".
at _loop (/home/you/project/node_modules/prettier/bin-prettier.js:7887:63)
at Normalizer._applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:8000:13)
at applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:7817:49)
at Normalizer.normalize (/home/you/project/node_modules/prettier/bin-prettier.js:7823:9)
at normalizeOptions$1 (/home/you/project/node_modules/prettier/bin-prettier.js:8760:31)
at Object.normalizeApiOptions (/home/you/project/node_modules/prettier/bin-prettier.js:8918:10)
at getOptionsForFile (/home/you/project/node_modules/prettier/bin-prettier.js:44160:69)
at /home/you/project/node_modules/prettier/bin-prettier.js:44214:22
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:21531) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:21531) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

# Prettier 1.19
$ prettier --parser babel < test.js
[error] Invalid printWidth value. Expected an integer, but received "nope".

Gracefully handle nonexistent paths passed to --stdin-filepath (#6687 by @voithos and @lydell)

Previously, if you passed a nonexistent subdirectory to --stdin-filepath, Prettier would throw an error. Now, Prettier gracefully handles this.

# Prettier 1.18
$ prettier --stdin-filepath does/not/exist.js < test.js
[error] Invalid configuration file: ENOENT: no such file or directory, scandir '/home/you/project/does/not'

# Prettier 1.19
$ prettier --stdin-filepath does/not/exist.js < test.js
test;

Config should not be evaluated for ignored files (#6233 by @jamesreggio)

Prior to this change, the CLI would resolve the config for a file before checking it against the ignored list. If the config was invalid, the CLI would report a failure.

This change relocates the config-resolution phase until after the file is confirmed to not be ignored.

Display invalid config filename in error message (#6865 by @fisker)

# Input
$ prettier filename.js --config .invalid-config

# Prettier 1.18
Invalid configuration file: ...

# Prettier 1.19
Invalid configuration file `.invalid-config`: ...

Other

Thanks to @fisker for updating lots of Prettier’s dependencies!

VS Code: add support for .mongo files (#6848 by @aymericbouzy)

When using the Azure Cosmos DB extension for VS Code, you can create .mongo files to write MongoDB queries, which use Javascript syntax. This change allows VS Code to format your file using Prettier.

db.users.find({ someField: { $exists: true } });