Hoppa till huvudinnehållet

Prettier 2.1: nytt alternativ --embedded-language-formatting och nya JavaScript/TypeScript-funktioner!

· 34 min att läsa
Inofficiell Beta-översättning

Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →

Den här versionen introducerar ett nytt alternativ --embedded-language-formatting, stödjer nya JavaScript/TypeScript-funktioner och innehåller många buggfixar och förbättringar!

Höjdpunkter

API

Lägg till alternativet --embedded-language-formatting={auto,off} (#7875 av @bakkot, #8825 av @fisker)

När Prettier identifierar att du har placerat kod den kan formatera inuti en sträng i en annan fil – som i en taggad mall i JavaScript med en tagg som heter html eller i kodblock i Markdown – kommer den som standard att försöka formatera den koden.

Ibland är detta beteende oönskat eftersom det kan ändra hur din kod fungerar. Det här alternativet låter dig växla mellan standardbeteendet (auto) och att stänga av funktionen helt (off). Det gäller alla språk där Prettier känner igen inbäddad kod, inte bara JavaScript.

// Input
html`
<p>
I am expecting this to come out exactly like it went in.
`;

// using --embedded-language-formatting=auto (or omitting this option)
html`
<p>
I am expecting this to come out exactly like it went in.
</p>
`;

// using --embedded-language-formatting=off
html`
<p>
I am expecting this to come out exactly like it went in.
`;

TypeScript

Stöd för TypeScript 4.0

Märkta tupel-element (#8885 av @fisker, #8982 av @sosukesuzuki)
// Input
type Range = [start: number, end: number];

// Prettier 2.0
SyntaxError: Unexpected token, expected "," (1:20)
> 1 | type Range = [start: number, end: number];

// Prettier 2.1
type Range = [start: number, end: number];
Kortslutande tilldelningsoperatorer (#8982 av @sosukesuzuki)
// Input
a ||= b;

// Prettier 2.0
SyntaxError: Expression expected. (1:5)
> 1 | a ||= b;

// Prettier 2.1
a ||= b;
Typannoteringar för catch-satser (#8805 av @fisker)
// Input
try {} catch (e: any) {}

// Prettier 2.0
try {
} catch (e) {}

// Prettier 2.1
try {
} catch (e: any) {}

Andra ändringar

JavaScript

Stöd för F#- och Smart-pipeline-operatorförslagen (#6319 av @sosukesuzuki, @thorn0, #7979 av @sosukesuzuki)

F#-stil Pipeline:

// Input
promises |> await;

// Output (Prettier 2.0)
SyntaxError: Unexpected token (1:18)
> 1 | promises |> await;
| ^

// Output (Prettier 2.1)
promises |> await;

Smart Pipeline:

// Input
5 |> # * 2

// Output (Prettier 2.0)
SyntaxError: Unexpected character '#' (1:6)
> 1 | 5 |> # * 2
| ^

// Output (Prettier 2.1)
5 |> # * 2

Fixa kommentarer i slutet av raden om de följs av efterföljande blanksteg (#8069 av @shisama)

Om en kommentarsrad hade efterföljande blanksteg, upptäcktes inte kommentaren som en radslutskommentar.

// Input
var a = { /* extra whitespace --> */
b };

var a = { /* no whitespace --> */
b };

// Prettier 2.0
var a = {
/* extra whitespace --> */

b,
};

var a = {
/* no whitespace --> */ b,
};

// Prettier 2.1
var a = {
/* extra whitespace --> */ b,
};

var a = {
/* no whitespace --> */ b,
};

Åtgärda inkonsekvent tolkning av injicerade uttryck i styled-components malliteraler (#8097 av @thecodrr)

// Input
const SingleConcat = styled.div`
${something()}
& > ${Child}:not(:first-child) {
margin-left:5px;
}
`

const MultiConcats = styled.div`
${something()}
& > ${Child}${Child2}:not(:first-child) {
margin-left:5px;
}
`

const SeparatedConcats = styled.div`
font-family: "${a}", "${b}";
`

// Prettier 2.0 -- same as input

// Prettier 2.1
const SingleConcat = styled.div`
${something()}
& > ${Child}:not(:first-child) {
margin-left: 5px;
}
`;

const MultiConcats = styled.div`
${something()}
& > ${Child}${Child2}:not(:first-child) {
margin-left: 5px;
}
`;

const SeparatedConcats = styled.div`
font-family: "${a}", "${b}";
`;

Åtgärda att efterföljande kommatecken i objekt ignoreras för sista egenskapen (#8111 av @fisker)

// Input
const foo = {
// prettier-ignore
bar: "baz"
}

// Prettier 2.0
const foo = {
// prettier-ignore
bar: "baz"
};

// Prettier 2.1
const foo = {
// prettier-ignore
bar: "baz",
};

Behåll objektnyckel med escape-sekvens oförändrad (#8160 av @fisker)

// Input
const a = {
"\u2139": 'why "\\u2139" converted to "i"?',
};

// Prettier 2.0
const a = {
: 'why "\\u2139" converted to "i"?',
};


// Prettier 2.1
const a = {
"\u2139": 'why "\\u2139" is converted to "i"?',
};

Åtgärda extra mellanslag efter minus i CSS-in-JS (#8255 av @thorn0)

// Input
css`
color: var(--global--color--${props.color});
`

// Prettier 2.0
css`
color: var(--global--color-- ${props.color});
`;

// Prettier 2.1
css`
color: var(--global--color--${props.color});
`;

Åtgärda kommentarer i extends-delen av klassdeklarationer/uttryck (#8312 av @thorn0)

// Input
class a extends a // comment
{
constructor() {}
}

// Prettier 2.0
class a extends a // comment {
constructor() {}
}

// Prettier 2.1
class a extends a { // comment
constructor() {}
}

Radbryt inte arrayer i Jests test.each-mallsträngar (#8354 av @yogmel)

// Input
test.each`
a | b | c
${1} | ${[{ start: 1, end: 3 },{ start: 15, end: 20 },]} | ${[]}
`("example test", ({a, b, c}) => {})

// Prettier 2.0
test.each`
a | b | c
${1} | ${[
{ start: 1, end: 3 },
{ start: 15, end: 20 }
]} | ${[]}
`("example test", ({ a, b, c }) => {});

// Prettier 2.1
test.each`
a | b | c
${1} | ${[{ start: 1, end: 3 }, { start: 15, end: 20 }]} | ${[]}
`("example test", ({ a, b, c }) => {});

Stöd insertPragma och requirePragma i filer med shebang (#8376 av @fisker)

// `--insert-pragma`
// Input
#!/usr/bin/env node
hello
.world();

// Prettier 2.0
SyntaxError: Unexpected token (3:1)
1 | /** @format */
2 |
> 3 | #!/usr/bin/env node
| ^
4 | hello
5 | .world();

// Prettier 2.1
#!/usr/bin/env node
/** @format */

hello.world();

// `--require-pragma`
// Input
#!/usr/bin/env node
/**
* @format
*/
hello
.world();

// Prettier 2.0
#!/usr/bin/env node
/**
* @format
*/
hello
.world();

// Prettier 2.1
#!/usr/bin/env node
/**
* @format
*/
hello.world();

Åtgärda indrag vid intervallformatering (#8410 av @thorn0)

> echo -e "export default class Foo{\n/**/\n}" | prettier --range-start 16 --range-end 31 --parser babel
// Prettier 2.0
export default class Foo {
/**/
}

// Prettier 2.1
export default class Foo {
/**/
}

Förbättra identifiering av källelement för intervallformatering (#8419 av @thorn0)

Inte alla sats-typer identifierades (läs här om hur intervallformatering fungerar i Prettier).

// Input
for (const element of list) { /* ... */ }
// ^^^^^^^^^^^^^^^^^^^^^^ ← range

// Prettier 2.0
for (const element of list) { /* ... */ }

// Prettier 2.1
for (const element of list) {
/* ... */
}

Stöd Privata Fält i in (#8431 av @sosukesuzuki)

Stöder Stage-2-förslaget Private Fields in in.

// Input
#prop in obj;

// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #prop in obj;
| ^
2 |

// Prettier 2.1
#prop in obj;

Stöd ES Module Attributes och JSON-moduler (#8436 av @fisker)

Stöder Stage-2-förslaget ES Module Attributes and JSON modules.

// Input
import foo from "foo.json" with type: "json";

// Prettier 2.0
SyntaxError: Unexpected token, expected ";" (1:28)
> 1 | import foo from "foo.json" with type: "json";
| ^

// Prettier 2.1
import foo from "foo.json" with type: "json";

Stöd record- och tuple-syntax (#8453 av @fisker)

Stöder Stage-2-förslaget JavaScript Records & Tuples Proposal.

Stöder endast #[]/#{}-syntaxen, inte {| |} / [| |].

Tupler

// Input
#[1, 2, 3]

// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #[1, 2, 3]
| ^


// Prettier 2.1
#[1, 2, 3];

Record

// Input
#{
a: 1,
b: 2,
c: 3,
}

// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #{
| ^
2 | a: 1,
3 | b: 2,
4 | c: 3,


// Prettier 2.1
#{
a: 1,
b: 2,
c: 3,
};

Sätt parenteser runt JSX-element till vänster om "<" (#8461 av @sosukesuzuki)

// Input
(<div/>) < 5;

// Prettier 2.0
<div/> < 5;

// Prettier 2.0 second output
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (1:9)
> 1 | <div /> < 5;
| ^
2 |

// Prettier 2.1
(<div />) < 5;

Åtgärda indrag för binära uttryck med efterföljande kommentarer (#8476 av @sosukesuzuki)

// Input
a +
a + // comment
a;

// Prettier 2.0
a +
a + // comment
a;

// Prettier 2.1
a +
a + // comment
a;

Fixa instabila kommentarer i binära uttryck (#8491 av @thorn0)

// Input
Math.min(
(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight)
) - devsite_footer_height,
0,
)

// Prettier 2.0 (first output)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);

// Prettier 2.0 (second output)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);

// Prettier 2.1 (first and second outputs)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);
// Input
const topOfDescriptionBox =
Layout.window.width + // Images are 1:1 aspect ratio, full screen width
Layout.headerHeight;

// Prettier 2.0 (first output)
const topOfDescriptionBox =
Layout.window.width + Layout.headerHeight; // Images are 1:1 aspect ratio, full screen width

// Prettier 2.0 (second output)
const topOfDescriptionBox = Layout.window.width + Layout.headerHeight; // Images are 1:1 aspect ratio, full screen width

// Prettier 2.1 (first and second outputs)
const topOfDescriptionBox =
Layout.window.width + // Images are 1:1 aspect ratio, full screen width
Layout.headerHeight;

Lägg till och ta bort citationstecken för numeriska nycklar (#8508 av @lydell)

Prettier tar bort citationstecken från objektnycklar om de är identifierare. Nu tar Prettier även bort citationstecken från objektnycklar som är siffror.

Om du använder quoteProps: "consistent" kan Prettier också lägga till citationstecken för numeriska nycklar så att alla egenskaper får citationstecken.

// Input
x = {
"a": null,
"1": null,
};

// Prettier 2.0
x = {
a: null,
"1": null,
};

// Prettier 2.1
x = {
a: null,
1: null,
};

Prettier ändrar endast "enkla" siffror som 1 och 123.5. Den gör inte följande transformationer då de kan upplevas som oväntade:

1e2 -> "100"
0b10 -> "10"
1_000 -> "1000"
1.0 -> "1"
0.99999999999999999 -> "1"
999999999999999999999 -> "1e+21"
2n -> "2"

"1e+100" -> 1e100

(Använd inte förvirrande siffror som objektnycklar!)

Observera att Prettier endast tar bort citationstecken för siffror med "babel"-parsern. Det är inte helt säkert att göra detta i TypeScript.

Föredra inledande kommentar när det finns en kommentar efter "?" i villkorliga typer (#8557 av @sosukesuzuki)

// Input
type A = B extends T
? // comment
foo
: bar;

// Prettier 2.0
type A = B extends T // comment
? foo
: bar;

// Prettier 2.1
type A = B extends T
? // comment
foo
: bar;

Bryt ternära uttryck som innehåller flerradskommentarer (#8592 av @sosukesuzuki)

// Input
test
? /* comment
comment
*/
foo
: bar;

// Prettier 2.0
test ? /* comment
comment
*/ foo : bar;

// Prettier 2.1
test
? /* comment
comment
*/
foo
: bar;

Fixa instabila kommentarspar mellan klassmetoder (#8731 av @fisker)

// Input
class C {
ma() {} /* D */ /* E */
mb() {}
}

// Prettier 2.0
class C {
ma() {} /* E */ /* D */
mb() {}
}

// Prettier 2.0 (Second format)
class C {
ma() {} /* D */ /* E */
mb() {}
}

// Prettier 2.1
class C {
ma() {} /* D */ /* E */
mb() {}
}

Fixa duplicerade prettier-ignore-kommentarer (#8742 av @fisker)

// Input
a = <div {.../* prettier-ignore */{}}/>
a = <div {...{}/* prettier-ignore */}/>

// Prettier 2.0
a = <div {/* prettier-ignore */ .../* prettier-ignore */ {}} />;
a = <div {...{} /* prettier-ignore */ /* prettier-ignore */} />;

// Prettier 2.1
a = <div {.../* prettier-ignore */ {}} />;
a = <div {...{} /* prettier-ignore */} />;

Stöd för Decimal-propositionen (#8901 av @fisker)

Stöder Stage-1-propositionen Decimal Proposal.

// Input
0.3m;

// Prettier 2.0
SyntaxError: Identifier directly after number (1:4)
> 1 | 0.3m;

// Prettier 2.1
0.3m;

Lägg till parenteser vid yielding av JSX (#9011 av @fisker)

I v2.0.0 tog vi bort parenteser vid yielding av JSX, vilket fungerar för de flesta parsers, men ESLint kastar fel vid parsning, relaterat issue.

// Input
function* f() {
yield <div>generator</div>
}

// Prettier 2.0
function* f() {
yield <div>generator</div>
}

// Prettier 2.1
function* f() {
yield (<div>generator</div>);
}

TypeScript

Fixa babel-ts-parsern så att den ger korrekt syntaxfel för (a:b) (#8046 av @thorn0)

Tidigare parsades sådan kod utan fel, men ett fel kastades i printningen och felet visades på ett otydligt sätt med stackspår. Nu kastas ett korrekt syntaxfel av parsern.

// Input
(a:b)

// Prettier 2.0
[error] test.ts: Error: unknown type: "TSTypeCastExpression"
[error] ... [a long stack trace here] ...

// Prettier 2.1
[error] test.ts: SyntaxError: Did not expect a type annotation here. (1:2)
[error] > 1 | (a:b)
[error] | ^
[error] 2 |

Parentesera strängliteraler för att undvika tolkning som direktiv (#8422 av @thorn0)

Prettier sätter parenteser kring strängliteraler i statements-position eftersom dessa annars kan tolkas som direktiv om de förekommer överst i en funktion eller program, vilket kan ändra programmets beteende. Tekniskt sett är detta inte nödvändigt för strängar som inte är på första raden i en funktion eller program. Men att göra det ändå ger mer konsekvens och kan uppmärksamma buggar. Se till exempel den här Twitter-tråden.

Tidigare fungerade detta inte konsekvent för typescript-parsern. Endast strängar som redan var omslutna av parenteser behöll dem.

// Input
f();
'use foo';
('use bar');

// Prettier 2.0
f();
"use foo";
("use bar");

// Prettier 2.1
f();
("use foo");
("use bar");

Stöd för brytande ändring i TypeScript 3.9 för Optional Chaining och Non-Null Assertions (#8450 av @sosukesuzuki)

Se https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#breaking-changes

// Input
(a?.b)!.c;

// Prettier 2.0
a?.b!.c;

// Prettier 2.1
(a?.b)!.c;

Flow

Åtgärdar funktionstyp med nullable-parametrar (#8365 av @fisker)

// Input
let f: <A>(
((?A) => B),
) => B;

// Prettier 2.0
let f: <A>((?A) => B) => B;

// Prettier 2.0 (Second format)
SyntaxError: Unexpected token (1:12)
> 1 | let f: <A>((?A) => B) => B;

// Prettier 2.1
let f: <A>(((?A) => B)) => B;

Åtgärdar export default för Flow Enum (#8768 av @gkz)

Lägger inte till avslutande semikolon vid export av Flow Enum som default.

// Input
export default enum B {}

// Prettier 2.0
export default enum B {};

// Prettier 2.1
export default enum B {}

CSS

Bryter inte kod med kommentar i slutet av at-rule (#7009 av @evilebottnawi)

/* Input */
@at-root .foo
// .bar
{

}

/* Prettier 2.0 */
@at-root .foo
// .bar {
}

/* Prettier 2.1 */
@at-root .foo
// .bar
{
}

Åtgärdar manipulering av url() utan citationstecken (#7592 av @mattiacci)

Förbättrar hanteringen av URL-innehåll utan citationstecken i CSS/SCSS/Less. Detta löser inte de underliggande parsningsproblemen men säkerställer att Prettier inte ändrar URL:er.

/* Input */
@import url(https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&display=swap);
@import url(//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap);
.validUnquotedUrls{
background: url(data/+0ThisShouldNotBeLowerCased);
background: url(https://foo/A*3I8oSY6AKRMAAAAAAAAAAABkARQnAQ);
background: url(https://example.com/some/quite,long,url,with,commas.jpg);
}

/* Prettier 2.0 */
@import url(
https://fonts.googleapis.com/css?family=Roboto:100,
300,
400,
500,
700,
900&display=swap
);
@import url(
//fonts.googleapis.com/css?family=#{get-font-family("Roboto")}:100,
300,
500,
700,
900&display=swap
);
.validUnquotedUrls {
background: url(data/+0thisshouldnotbelowercased);
background: url(https://foo/A*3i8osy6akrmaaaaaaaaaaabkarqnaq);
background: url(https://example.com/some/quite, long, url, with, commas.jpg);
}


/* Prettier 2.1 */
@import url(https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&display=swap);
@import url(//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap);
.validUnquotedUrls{
background: url(data/+0ThisShouldNotBeLowerCased);
background: url(https://foo/A*3I8oSY6AKRMAAAAAAAAAAABkARQnAQ);
background: url(https://example.com/some/quite,long,url,with,commas.jpg);
}

Felaktigt blanktecken efter escape-kolon i CSS-grid-linjens namn (#8535 av @boyenn)

/* Input */
.grid {
grid-template-rows:
[row-1-00\:00] auto;
}

/* Prettier 2.0 */
.grid {
grid-template-rows: [row-1-00\: 00] auto;
}

/* Prettier 2.1 */
.grid {
grid-template-rows: [row-1-00\:00] auto;
}

Stöd för @supports selector(<custom-selector>) (#8545 av @boyenn)

/* Input */
@supports selector(:focus-visible) {
button:focus {
outline: none;
}

button:focus-visible {
outline: 2px solid orange;
}
}

/* Prettier 2.0 */
@supports selector(: focus-visible) {
button:focus {
outline: none;
}

button:focus-visible {
outline: 2px solid orange;
}
}

/* Prettier 2.1 */
@supports selector(:focus-visible) {
button:focus {
outline: none;
}

button:focus-visible {
outline: 2px solid orange;
}
}

Förbättrad hantering av godtyckliga argument (#8567, #8566 av @boyenn)

Prettier lägger inte längre till extra blanksteg efter funktion när godtyckliga argument skickas. Prettier bryter inte längre kod när inline-nummerlistor används som godtyckliga argument.

/* Input */
body {
test: function($list...);
foo: bar(returns-list($list)...);
background-color: rgba(50 50 50 50...);
}

/* Prettier 2.0 */
body {
test: function($list...);
foo: bar(returns-list($list) ...);
background-color: rgba(50 50 50 50..);
}

/* Prettier 2.1 */
body {
test: function($list...);
foo: bar(returns-list($list)...);
background-color: rgba(50 50 50 50...);
}

SCSS

Åtgärdar extra indrag efter kommentarer i SCSS (#7844 av @boyenn)

Tidigare lade Prettier till extra indrag på rader efter kommentarer i SCSS-kartor. Prettier gör nu inte dessa indrag längre.

/* Input */
$my-map: (
'foo': 1, // Foo
'bar': 2, // Bar
);

/* Prettier 2.0 */
$my-map: (
"foo": 1,
// Foo
"bar": 2,
// Bar
);

/* Prettier 2.1 */
$my-map: (
"foo": 1,
// Foo
"bar": 2,
// Bar
);

Åtgärdar inline-kommentarer mellan egenskap och värde (#8366 av @fisker)

// Input
a {
color: // comment
red;
}

// Prettier 2.0
a {
color: // comment red;
}

// Prettier 2.1
a {
color: // comment
red;
}

Kommentarer i filslut försvann vid utelämnat semikolon (#8675 av @fisker)

// Input
@mixin foo() {
a {
color: #f99;
}
}

@include foo() /* comment*/

// Prettier 2.0
@mixin foo() {
a {
color: #f99;
}
}

@include foo();

// Prettier 2.1
@mixin foo() {
a {
color: #f99;
}
}

@include foo(); /* comment*/

Less

Fixa :extend pseudoklass (#8178 av @fisker)

Selektorn tolkades tidigare som ett värde, nu erkänns den som en selektor.

// Input
.hello {
&:extend(.input[type="checkbox"]:checked ~ label)}

// Prettier 2.0
.hello {
&:extend(.input[type= "checkbox" ]: checked ~label);
}

// Prettier 2.1
.hello {
&:extend(.input[type="checkbox"]:checked ~ label);
}

Fixa inline-kommentarer som innehåller /* (#8360 av @fisker)

När inline-kommentarer innehåller /* skrivs vissa andra kommentarer inte ut korrekt.

// Input
@import "a";

// '/*' <-- this breaks formatting

@import 'b';
/* block */
/*no-space block*/

// Prettier 2.0
@import "a";

// '/*' <-- this breaks formatting

@import "b";

@import 'b
@import 'b';
/* bl

// Prettier 2.1
@import "a";

// '/*' <-- this breaks formatting

@import "b";
/* block */
/*no-space block*/

HTML

Utelämna avslutande semikolon för enrads stilattribut (#8013 av @bschlenk)

<!-- Input -->
<div style="margin: 0; padding: 20px"></div>
<div style="margin: 0; padding: 20px; position: relative; display: inline-block; color: blue"></div>

<!-- Prettier 2.0 -->
<div style="margin: 0; padding: 20px;"></div>
<div
style="
margin: 0;
padding: 20px;
position: relative;
display: inline-block;
color: blue;
"
></div>

<!-- Prettier 2.1 -->
<div style="margin: 0; padding: 20px"></div>
<div
style="
margin: 0;
padding: 20px;
position: relative;
display: inline-block;
color: blue;
"
></div>

Bevara icke-ASCII blanktecken i HTML (#8137 av @fisker)

Icke-ASCII blanktecken som U+00A0 U+2005 etc. betraktas inte som blanktecken i html och bör inte tas bort.

// Prettier 2.0
[...require("prettier").format("<i> \u2005 </i>", { parser: "html" })]
.slice(3, -5)
.map((c) => c.charCodeAt(0).toString(16));

// -> [ '20' ]
// `U+2005` is removed

// Prettier 2.1
[...require("prettier").format("<i> \u2005 </i>", { parser: "html" })]
.slice(3, -5)
.map((c) => c.charCodeAt(0).toString(16));

// -> [ '20', '2005', '20' ]

Stöd för äldre HTML-liknande kommentarer i skriptblock (#8173 av @fisker, #8394 av @fisker)

Tidigare tolkade vi html <script>-block som "module" (ECMAScript Module-grammatik), vilket är anledningen till att vi inte kunde tolka kommentarer som börjar med <!-- (så kallade HTML-liknande kommentarer). Nu tolkar vi <script>-block som "script", såvida inte detta <script>:

  1. Har type="module"

  2. Har type="text/babel" och data-type="module", introducerat i babel@v7.10.0

<!-- Input -->
<SCRIPT>
<!--
alert("hello" + ' world!')
//--></SCRIPT>

<!-- Prettier 2.0 -->
SyntaxError: Unexpected token (2:1)
1 |
> 2 | <!--
| ^
3 | alert("hello" + ' world!')
4 | //-->

<!-- Prettier 2.1 -->
<script>
<!--
alert("hello" + " world!");
//-->
</script>

Behandla <select> som inline-block och <optgroup>/<option> som block (#8275 av @thorn0, #8620 av @fisker)

Nu vet Prettier att det är säkert att lägga till blanktecken inuti select, option och optgroup-taggar.

<!-- Input -->
<select><option>Blue</option><option>Green</option><optgroup label="Darker"><option>Dark Blue</option><option>Dark Green</option></optgroup></select>

<!-- Prettier 2.0 -->
<select
><option>Blue</option
><option>Green</option
><optgroup label="Darker"
><option>Dark Blue</option><option>Dark Green</option></optgroup
></select
>

<!-- Prettier 2.1 -->
<select>
<option>Blue</option>
<option>Green</option>
<optgroup label="Darker">
<option>Dark Blue</option>
<option>Dark Green</option>
</optgroup>
</select>

Fixa brutna URL:er med kommatecken i srcset (#8359 av @fisker)

<!-- Input -->
<img
srcset="
_20200401_145009_szrhju_c_scale,w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,w_1400.jpg 1400w"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
>

<!-- Prettier 2.0 -->
<img
srcset="
_20200401_145009_szrhju_c_scale,
w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,
w_1400.jpg 1400w
"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
/>

<!-- Prettier 2.1 -->
<img
srcset="
_20200401_145009_szrhju_c_scale,w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,w_1400.jpg 1400w
"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
/>

Stöd för <script type="text/html> (#8371 av @sosukesuzuki)

<!-- Input -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>

<!-- Prettier 2.0 -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>

<!-- Prettier 2.1 -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>

Stöd för front matter med dynamiskt språk (#8381 av @fisker)

Stöd för dynamisk språkdetektering i front matter, även tillgängligt för css, less, scss och markdown-parser.

<!-- Input -->
---my-awsome-language
title: Title
description: Description
---
<h1>
prettier</h1>

<!-- Prettier 2.0 -->
---my-awsome-language title: Title description: Description ---

<h1>
prettier
</h1>

<!-- Prettier 2.1 -->
---my-awsome-language
title: Title
description: Description
---

<h1>
prettier
</h1>

Bevara inte radbrytningar runt textbara innehåll (#8614 av @fisker)

Tidigare behöll Prettier alltid radbrytningar kring inline-noder (t.ex. inline-element, text, interpoleringar). Generellt försöker Prettier så långt möjligt undvika att förlita sig på ursprungsformatering, men det finns minst två fall där det är oönskvärt att slå ihop inline-noder till en enda rad: listliknande innehåll och villkorskonstruktioner (som v-if/v-else i Vue). Ett bra sätt att upptäcka dessa fall kunde inte hittas, så ett sådant kompromissbeslut togs. Det visade sig dock att för rent textinnehåll var denna regeluppmjukning onödig och ledde bara till förvirrande inkonsekvent formatering.

<!-- Input -->
<div>
Hello, world!
</div>
<div>
Hello, {{ username }}!
</div>

<!-- Prettier 2.0 -->
<div>
Hello, world!
</div>
<div>Hello, {{ username }}!</div>

<!-- Prettier 2.1 -->
<div>Hello, world!</div>
<div>Hello, {{ username }}!</div>

Känner igen kända HTML-taggar (#8621 av @fisker)

<!-- Input -->
<div>before<details><summary>summary long long long long </summary>details</details>after</div>
<div>before<dialog open>dialog long long long long long long long long </dialog>after</div>
<div>before<object data="horse.wav"><param name="autoplay" value="true"/><param name="autoplay" value="true"/></object>after</div>

<!-- Prettier 2.0 -->
<div>
before<details><summary>summary long long long long </summary>details</details
>after
</div>
<div>
before<dialog open>dialog long long long long long long long long </dialog
>after
</div>
<div>
before<object data="horse.wav"
><param name="autoplay" value="true" /><param
name="autoplay"
value="true" /></object
>after
</div>

<!-- Prettier 2.1 -->
<div>
before
<details>
<summary>summary long long long long</summary>
details
</details>
after
</div>
<div>
before
<dialog open>dialog long long long long long long long long</dialog>
after
</div>
<div>
before<object data="horse.wav">
<param name="autoplay" value="true" />
<param name="autoplay" value="true" /></object
>after
</div>

Fixa formatering av element med void-element som sista barn (#8643 av @ikatyang)

<!-- Input -->
<video controls width="250">
<source src="/media/examples/flower.webm"
type="video/webm">
<source src="/media/examples/flower.mp4"
type="video/mp4"
></video>text after

<!-- Prettier 2.0 -->
<video controls width="250">
<source src="/media/examples/flower.webm" type="video/webm" />
<source src="/media/examples/flower.mp4" type="video/mp4" /></video

>text after

<!-- Prettier 2.1 -->
<video controls width="250">
<source src="/media/examples/flower.webm" type="video/webm" />
<source src="/media/examples/flower.mp4" type="video/mp4" /></video
>text after

Vue

Förbättra formatering av Vue SFC-rotblock (#8023 av @sosukesuzuki, #8465 av @fisker)

Stödjer formatering av alla språkblock (inklusive anpassade block med lang-attribut) med inbyggda parsrar och tillägg.

<!-- Input -->
<template lang="pug">
div.text( color = "primary", disabled ="true" )
</template>
<i18n lang="json">
{
"hello": 'prettier',}
</i18n>

<!-- Prettier 2.0 -->
<template lang="pug">
div.text( color = "primary", disabled ="true" )
</template>
<i18n lang="json">
{
"hello": 'prettier',}
</i18n>

<!-- Prettier 2.1 -->
<template lang="pug">
.text(color="primary", disabled="true")
</template>
<i18n lang="json">
{
"hello": "prettier"
}
</i18n>

@prettier/plugin-pug krävs för detta exempel.

Förbättra parsning av anpassade block (#8153 av @sosukesuzuki)

<!-- Input -->
<custom lang="javascript">
const foo = "</";
</custom>

<!-- Prettier 2.0 -->
SyntaxError: Unexpected character """ (2:19)
[error] 1 | <custom lang="javascript">
[error] > 2 | const foo = "</";
[error] | ^
[error] 3 | </custom>

<!-- Prettier 2.1 -->
<custom lang="javascript">
const foo = "</";
</custom>

Fixa trasig formatering med versal HTML-tagg (#8280 av @fisker)

<!-- Input -->
<!doctype html><HTML></HTML>

<!-- Prettier 2.0 -->
<!DOCTYPE html>><HTML></HTML>

<!-- Prettier 2.1 -->
<!DOCTYPE html><HTML></HTML>

Fixa ful formatering för enrads-template i Vue SFC (#8325 av @sosukesuzuki)

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

<!-- Prettier 2.0 -->
<template
><p>foo</p>
<div>foo</div></template
>

<!-- Prettier 2.1 -->
<template>
<p>foo</p>
<div>foo</div>
</template>

Stödja Vue DOM-mall (#8326 av @sosukesuzuki)

Vid användning av vue-parse för HTML, parsa mall som HTML.

<!-- Input -->
<!DOCTYPE html>
<html>
<body STYLE="color: #333">
<DIV id="app">
<DIV>First Line</DIV><DIV>Second Line</DIV>
</DIV>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {}
},
});
</script>
</body>
</html>

<!-- Prettier 2.0 -->
<!DOCTYPE html>
<html>
<body STYLE="color: #333">
<DIV id="app"> <DIV>First Line</DIV><DIV>Second Line</DIV> </DIV>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {};
},
});
</script>
</body>
</html>

<!-- Prettier 2.1 -->
<!DOCTYPE html>
<html>
<body style="color: #333">
<div id="app">
<div>First Line</div>
<div>Second Line</div>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {};
},
});
</script>
</body>
</html>

Förbättra formatering av versal HTML-tagg i DOM-mall (#8337 av @sosukesuzuki)

<!-- Input -->
<!DOCTYPE html><HTML>
<body>
<div v-if="foo === 'foo'">

</div>
<script>
new Vue({el: '#app'})
</script>
</body>
</HTML>

<!-- Prettier 2.0 -->
<!DOCTYPE html>
<HTML>
<body>
<div v-if="foo === 'foo'">

</div>
<script>
new Vue({el: '#app'})
</script>
</body>
</HTML>

<!-- Prettier 2.1 -->
<!DOCTYPE html>
<HTML>
<body>
<div v-if="foo === 'foo'"></div>
<script>
new Vue({ el: "#app" });
</script>
</body>
</HTML>

Fixa formatering av interpolation inom parenteser (#8747 av @fisker)

<!-- Input -->
<template>
<span>{{(a|| b)}} {{z&&(a&&b)}}</span>
</template>

<!-- Prettier 2.0 -->
<template>
<span>{{(a|| b)}} {{z&&(a&&b)}}</span>
</template>

<!-- Prettier 2.1 -->
<template>
<span>{{ a || b }} {{ z && a && b }}</span>
</template>

Fixa att förkortade värden för namngivna slots inte formateras (#8839 av @wenfangdu)

<!-- Input -->
<template>
<div #default="{foo:{bar:{baz}}}"></div>
</template>

<!-- Prettier 2.0 -->
<template>
<div #default="{foo:{bar:{baz}}}"></div>
</template>

<!-- Prettier 2.1 -->
<template>
<div #default="{ foo: { bar: { baz } } }"></div>
</template>

Angular

Åtgärda frivillig kedjning med beräknade egenskaper och hantering av this (#8253 av @thorn0, #7942 av @fisker, fixar i angular-estree-parser av @ikatyang)

<!-- Input -->
{{ a?.b[c] }}
{{ a ( this )}}

<!-- Prettier 2.0 -->
{{ (a?.b)[c] }}
{{ a ( this )}}

<!-- Prettier 2.1 -->
{{ a?.b[c] }}
{{ a(this) }}

Bevara parenteser runt pipes i objektliteraler för kompatibilitet med AngularJS 1.x (#8254 av @thorn0)

<!-- Input -->
<div ng-style="{ 'color': ('#222' | darken)}"></div>

<!-- Prettier 2.0 -->
<div ng-style="{ color: '#222' | darken }"></div>

<!-- Prettier 2.1 -->
<div ng-style="{ 'color': ('#222' | darken)}"></div>

Handlebars (alfa)

Respektera singleQuote-alternativet för attributvärden som är mer komplexa än vanlig text (#8375 av @dcyriller)

{{!-- Input --}}
<a href='/{{url}}'></a>
<a href="/{{url}}"></a>

<a href='url'></a>
<a href="url"></a>

{{!-- Prettier 2.0 --}}
<a href="/{{url}}"></a>
<a href="/{{url}}"></a>

<a href='url'></a>
<a href='url'></a>

{{!-- Prettier 2.1 --}}
<a href='/{{url}}'></a>
<a href='/{{url}}'></a>

<a href='url'></a>
<a href='url'></a>

Åtgärda formatering av klassiska komponenter inuti element (#8593 av @mikoscz)

{{!-- Input --}}
<div>
{{classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>

{{!-- Prettier 2.0 --}}
<div>
{{
classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>

{{!-- Prettier 2.1 --}}
<div>
{{classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>

Stöd för att flytta en mustasch med ett omvänt snedstreck (#8634 av @dcyriller)

{{!-- Input --}}
\{{mustache}}
\\{{mustache}}
\\\{{mustache}}

{{!-- Prettier 2.0 --}}
{{mustache}}
\{{mustache}}
\\{{mustache}}

{{!-- Prettier 2.1 --}}
\{{mustache}}
\\{{mustache}}
\\\{{mustache}}

Formatera endast klassnamn i attribut (#8677 av @dcyriller)

{{!-- Input --}}
<div class=' class '></div>
<div title=' other attribute '></div>

{{!-- Prettier 2.0 --}}
<div class="class"></div>
<div title="other attribute"></div>

{{!-- Prettier 2.1 --}}
<div class="class"></div>
<div title=" other attribute "></div>

GraphQL

Förbättra radbrytning av GraphQL-fragmentdirektiv (#7721 av @sasurau4)

# Input
fragment TodoList_list on TodoList @argumentDefinitions(
count: {type: "Int", defaultValue: 10},
) {
title
}

# Prettier 2.0
fragment TodoList_list on TodoList
@argumentDefinitions(count: { type: "Int", defaultValue: 10 }) {
title
}

# Prettier 2.1
fragment TodoList_list on TodoList
@argumentDefinitions(count: { type: "Int", defaultValue: 10 }) {
title
}

Åtgärda kommentarer mellan gränssnitt (#8006 av @fisker)

# Input
type Type1 implements
A &
# comment 1
B
# comment 2
& C {a: a}

# Prettier 2.0
type Type1 implements A & # comment 1
B & # comment 2
C {
a: a
}

# Prettier 2.0 (Second format)
type Type1 implements A & B & C { # comment 1 # comment 2
a: a
}

# Prettier 2.1
type Type1 implements A &
# comment 1
B &
# comment 2
C {
a: a
}

Tillåt gränssnitt att implementera andra gränssnitt (#8007 av @fisker)

Se "RFC: Tillåt gränssnitt att implementera andra gränssnitt"

# Input
interface Resource implements Node {
id: ID!
url: String
}

# Prettier 2.0
interface Resource {
id: ID!
url: String
}

# Prettier 2.1
interface Resource implements Node {
id: ID!
url: String
}

Markdown

Uppdatera remark-parse till v8 (#8140 av @saramarcondes, @fisker, @thorn0)

remark, markdown-tolken som Prettier använder, har fått en länge väntad uppdatering (5.0.0 → 8.0.2, se remark's ändringslogg). Detta åtgärdade massor av gamla buggar, särskilt relaterade till tolkning av listobjekt indenterade med tabbar.

Observera att den nya versionen är strängare vid tolkning av fotnoter, en syntaxutökning som inte definieras i någon specifikation. Tidigare kunde Prettier tolka (och mata ut, beroende på alternativet --tab-width) flerradiga fotnoter indenterade med valfritt antal mellanslag. Den nya versionen känner bara igen flerradiga fotnoter indenterade med 4 mellanslag. Denna ändring anses inte vara brytande eftersom syntaxen inte är standardiserad, men om du råkar använda den, kan du före uppdatering av Prettier vilja använda en äldre version med --tab-width=4 för att göra fotnoterna i dina filer kompatibla med den nya versionen.

Formatera CJK-meningar med variationsväljare korrekt (#8511 av @ne-sachirou)

<!-- Input -->
麻󠄁羽󠄀‼️

<!-- Prettier 2.0 -->
麻 󠄁 羽 󠄀 ‼️

<!-- Prettier 2.1 -->
麻󠄁羽󠄀‼️

YAML

Rättar instabilt format med prettier-ignore (#8355 av @fisker)

# Input
# prettier-ignore
---
prettier: true
...
hello: world

# Prettier 2.0
# prettier-ignore
---
prettier: true
---
hello: world

# Prettier 2.0 (Second format)
# prettier-ignore
---
prettier: true

---
hello: world

# Prettier 2.1
# prettier-ignore
---
prettier: true
---
hello: world

Bevara tomma rader i kommentarer (#8356 av @fisker)

# Input
a:
- a: a

# - b: b

# - c: c

- d: d


b:
- a: a

# - b: b

# - c: c

# Prettier 2.0
a:
- a: a

# - b: b

# - c: c

- d: d

b:
- a: a
# - b: b
# - c: c

# Prettier 2.1
a:
- a: a

# - b: b

# - c: c

- d: d

b:
- a: a

# - b: b

# - c: c

Uppdaterar yaml och yaml-unist-parser (#8386 av @fisker, rättningar i yaml-unist-parser av @ikatyang)

# Input
# --- comments ---

# Prettier 2.0
--- # --- comments ---

# Prettier 2.1
# --- comments ---

# Input
empty block scalar: >

# comment

# Prettier 2.0
empty block scalar: >

# comment

# Prettier 2.1
SyntaxError: Block scalars with more-indented leading empty lines must use an explicit indentation indicator (1:21)
> 1 | empty block scalar: >
| ^
> 2 |
| ^^
> 3 | # comment
| ^^^^^^^^^^^

Rättar fel vid YAML Inline Extend-syntax (#8888 av @fisker, @evilebottnawi, rättningar i yaml-unist-parser av @ikatyang)

# Input
foo:
<<: &anchor
K1: "One"
K2: "Two"

bar:
<<: *anchor
K3: "Three"

# Prettier 2.0
SyntaxError: Merge nodes can only have Alias nodes as values (2:2)
1 | foo:
> 2 | <<: &anchor
| ^^^^^^^^^^^
> 3 | K1: "One"
| ^^^^^^^^^^^^
> 4 | K2: "Two"
| ^^^^^^^^^^^^
> 5 |
| ^
6 | bar:
7 | <<: *anchor
8 | K3: "Three"

# Prettier 2.1
foo:
<<: &anchor
K1: "One"
K2: "Two"

bar:
<<: *anchor
K3: "Three"

API

Lägger till pluginparsers till parser-alternativet (#8390 av @thorn0)

När en plugin definierar ett språk läggs dess parsers nu automatiskt till i listan över giltiga värden för parser-alternativet. Detta kan vara användbart för editorintegrationer eller andra applikationer som behöver en lista över tillgängliga parsers.

npm install --save-dev --save-exact prettier @prettier/plugin-php
const hasPhpParser = prettier
.getSupportInfo()
.options.find((option) => option.name === "parser")
.choices.map((choice) => choice.value)
.includes("php"); // false in Prettier 2.0, true in Prettier 2.1

Rättar prettier.getFileInfo() (#8548, #8551, #8585 av @fisker)

  • Vid användning av {resolveConfig: true} ska inferredParser nu vara den parser som lösts från konfigurationsfilen. Tidigare versioner kunde returnera felaktigt resultat för filer som stöds av inbyggda parsers.

  • Vid användning av {resolveConfig: true} och {ignorePath: "a/file/in/different/dir"} kunde inferredParser returnera felaktigt resultat.

  • Om angiven filePath ignoreras är inferredParser nu alltid null.

$ echo {"parser":"flow"}>.prettierrc
$ node -p "require('prettier').getFileInfo.sync('./foo.js', {resolveConfig: true})"

# Prettier 2.0
# { ignored: false, inferredParser: 'babel' }

# Prettier 2.1
# { ignored: false, inferredParser: 'flow' }
$ echo ignored.js>>.prettierignore
$ node -p "require('prettier').getFileInfo.sync('./ignored.js')"

# Prettier 2.0
# { ignored: true, inferredParser: 'babel' }

# Prettier 2.1
# { ignored: true, inferredParser: null }

Rättar editorConfig-lösning för filer i djupa kataloger (#8591 av @fisker)

Tidigare versioner kunde inte hitta .editorconfig för filer i djupa kataloger (djup större än 9 från projektrot, se #5705).

Stöd för .cjs och .json5 konfigurationsfiler (#8890, #8957 av @fisker)

Nya konfigurationsfilformat har lagts till:

  • .prettierrc.json5

  • .prettierrc.cjs

  • prettier.config.cjs

Åtgärda felaktigt intervallformat i filer med BOM (#8936 by @fisker)

När filer har BOM beräknades det faktiska intervallet felaktigt i tidigare versioner.

const text = "\uFEFF" + "foo = 1.0000;bar = 1.0000;";
// ^^^^^^^^^^^^^ Range
const result = require("prettier")
.format(text, {
parser: "babel",
rangeStart: 1,
rangeEnd: 13,
})
// Visualize BOM
.replace("\uFEFF", "<<BOM>>")
// Visualize EOL
.replace("\n", "<<EOL>>");

console.log(result);

// Prettier 2.0
// -> <<BOM>>foo = 1.0;<<EOL>>bar = 1.0;
// ^^^^^^^^^ This part should not be formatted

// Prettier 2.1
// -> <<BOM>>foo = 1.0;bar = 1.0000;

CLI

Åtgärda filnamn som innehåller CJK eller emoji som inte ignorerades korrekt (#8098 by @fisker)

// Prettier 2.0
$ echo "dir" > .prettierignore
$ prettier **/*.js -l
dir/😁.js
dir/中文.js
not-ignored.js

// Prettier 2.1
$ echo "dir" > .prettierignore
$ prettier **/*.js -l
not-ignored.js

--file-info respekterar .prettierrc och --no-config (#8586, #8830 by @fisker)

$ echo {"parser":"ninja"}>.prettierrc

# Prettier 2.0
$ prettier --file-info file.js
# { "ignored": false, "inferredParser": "babel" }
$ prettier --file-info file.js --no-config
# { "ignored": false, "inferredParser": "babel" }

# Prettier 2.1
$ prettier --file-info file.js
# { "ignored": false, "inferredParser": "ninja" }
$ prettier --file-info file.js --no-config
# { "ignored": false, "inferredParser": "babel" }

Lade till flaggan --ignore-unknown (alias -u) (#8829 by @fisker)

# Prettier 2.0
npx prettier * --check
Checking formatting...
foo.unknown[error] No parser could be inferred for file: foo.unknown
All matched files use Prettier code style!

# Prettier 2.1
npx prettier * --check --ignore-unknown
Checking formatting...
All matched files use Prettier code style!

Lade till aliaset -w för alternativet --write (#8833 by @fisker)

# Prettier 2.0
$ prettier index.js -w
[warn] Ignored unknown option -w. Did you mean -_?
"use strict";

module.exports = require("./src/index");

# Prettier 2.1
$ prettier index.js -w
index.js 30ms

Sluta föreslå -_ för okända alternativ (#8934 by @fisker)

# Prettier 2.0
$ prettier foo.js -a
[warn] Ignored unknown option -a. Did you mean -_?

# Prettier 2.1
$ prettier foo.js -a
[warn] Ignored unknown option -a. Did you mean -c?