Hoppa till huvudinnehållet

Prettier 3.2: Stöd för JSONC och Angulars ICU-uttryck

· 7 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 utgåvan innehåller nya funktioner som tillägg av en JSONC-parser, stöd för Angulars ICU-uttryck och många buggfixar.

Vi söker fortfarande feedback för alternativet --experimental-ternaries som släpptes i Prettier 3.1. Läs gärna A curious case of the ternaries och svara via den medföljande länken till Google Forms.

Dessutom rekommenderar vi att läsa Prettier's CLI: A Performance Deep Dive av Fabio Spampinato. Denna snabbare CLI är planerad att släppas som version 4.0.

Om du uppskattar Prettier och vill stödja vårt arbete, överväg att sponsra oss direkt via vår OpenCollective eller genom att sponsra de projekt vi förlitar oss på, såsom typescript-eslint, remark och Babel. Tack för ert fortsatta stöd!

Höjdpunkter

JSON

Ny jsonc-parser tillagd (#15831 av @fisker)

Tidigare antog vi att parsern för .jsonc-filer var json, men om vi ville behålla avslutande komma var vi tvungna att använda en krånglig lösning med konfigurationen {parser: "json5", quoteProps: "preserve", singleQuote: false}.

Den nya tillagda jsonc-parsern:

  • Sätter alltid citattecken runt objektnycklar.

  • Omsluter strängar med dubbla citattecken.

  • Respekterar förstås alternativet trailingComma.

Angular

Stöd för formatering av Angular ICU-uttryck (#15777 av @sosukesuzuki)

Stöd för två typer av Angular ICU-uttryck: plural och select.

<span i18n>
Updated:
{minutes, plural,
=0 {just now}
=1 {one minute ago}
other {{{minutes}} minutes ago}
}
</span>

<span i18n>
The author is {gender, select, male {male} female {female} other {other}}
</span>

Andra ändringar

JavaScript

Undvik att införa radbrytningar i mallinterpolationer (#15209 av @bakkot)

I en mallsträng som

`this is a long message which contains an interpolation: ${format(data)} <- like this`;

undvik att lägga till en radbrytning när uttrycket formateras, såvida en inte redan finns eller det är oundvikligt på grund av t.ex. en nästad funktion. Tidigare kunde en radbrytning införas när en interpolation i mallen var tillräckligt "inte enkel":

`this is a long message which contains an interpolation: ${format(
data,
)} <- like this`;

Nu kommer den istället att lämnas orörd.

Om en radbrytning redan finns inom ${...}, formateras den normalt.

Åtgärda icke-idempotent formatering av metodkedjor med tom rad (#15522 av @seiyab)

// Input
Foo.a()

.b();

// Prettier 3.1 (first format)
Foo.a()
.b();

// Prettier 3.1 (second format)
Foo.a().b();


// Prettier 3.2
Foo.a()

.b();

Åtgärda formatering av ternärer i funktionsanrop (#15677 av @fisker)

// Input
stopDirectory = await (useCache
? memoizedFindProjectRoot
: findProjectRootWithoutCache)(path.dirname(path.resolve(filePath)));

// Prettier 3.1
stopDirectory = await (useCache
? memoizedFindProjectRoot
: findProjectRootWithoutCache)(path.dirname(path.resolve(filePath)));

// Prettier 3.2
stopDirectory = await (
useCache ? memoizedFindProjectRoot : findProjectRootWithoutCache
)(path.dirname(path.resolve(filePath)));

Åtgärda inkonsekvenser för optional-chaining (#15806 av @fisker)

Inträffar endast vid användning av typescript, meriyah eller andra ESTree-parserar utom babel.

// Input
function someFunctionName() {
return isEqual(a.map(([t, _]) => t?.id), b.map(([t, _]) => t?.id));
return isEqual(a?.map(([t, _]) => t?.id), b?.map(([t, _]) => t?.id));
}
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere?.includes(listingId),
);

// Prettier 3.1
function someFunctionName() {
return isEqual(
a.map(([t, _]) => t?.id),
b.map(([t, _]) => t?.id),
);
return isEqual(a?.map(([t, _]) => t?.id), b?.map(([t, _]) => t?.id));
}
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere?.includes(listingId),
);

// Prettier 3.2
function someFunctionName() {
return isEqual(
a.map(([t, _]) => t?.id),
b.map(([t, _]) => t?.id),
);
return isEqual(
a?.map(([t, _]) => t?.id),
b?.map(([t, _]) => t?.id),
);
}
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere?.includes(listingId),
);

Åtgärda kommentarer i if (#15826 av @fisker)

// Input
if (foo) for (i = 2; i > 0; i--) console.log(i); // comment 1
else bar();

for (;;){
if (foo) continue; // comment 2
else bar();
}

// Prettier 3.1
Error: Comment "comment 2" was not printed. Please report this error!

// Prettier 3.2
if (foo)
for (i = 2; i > 0; i--) console.log(i); // comment 1
else bar();

for (;;) {
if (foo)
continue; // comment 2
else bar();
}

TypeScript

Förbättra layout för villkorliga typalias (#15811 av @seiyab)

// Input
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];

// Prettier 3.1
type FallbackFlags<F extends Flags | undefined> = Equals<
NonNullableFlag<F>["flags"],
{}
> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];

// Prettier 3.2
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];

HTML

Fixa formateringen av prettier-ignorerade oavslutade element (#15748 av @fisker)

<!-- Input -->
<!-- prettier-ignore -->
<h1>
Hello <span>world!

<!-- Prettier 3.1 -->
<!-- prettier-ignore -->
<h1>

<!-- Prettier 3.2 -->
<!-- prettier-ignore -->
<h1>
Hello <span>world!

Angular

Fixa prettier-ignore-ignorerade Angular-kontrollflödesblock (#15827 av @fisker)

<!-- Input -->
<!-- prettier-ignore -->
@if (condition) {
Foo
} @else {
Other
}

<!-- Prettier 3.1 -->
<!-- prettier-ignore -->
@if (condition) {
Foo
}
} @else {
Other
}

<!-- Prettier 3.2 -->
<!-- prettier-ignore -->
@if (condition) {
Foo
}
@else {
Other
}

Undvik att lägga till kolon för track i tredje uttrycket i for-block (#15887 av @sosukesuzuki)

<!-- Input -->
@for (item of items; let i = $index; track block) {}

<!-- Prettier 3.1 -->
@for (item of items; let i = $index; track: block) {}

<!-- Prettier 3.2 -->
@for (item of items; let i = $index; track block) {}

Ember / Handlebars

Bevara bokstavliga segments i sökvägar (#15605 av @maxpowa)

Åtgärdar scenarier där en input-Handlebars-fil med bokstavliga segments skulle formateras om på ett sätt som packar upp dessa segments, vilket orsakar syntaxfel i resultatet.

<!-- Input -->
{{input.[funky<api!response]}}
{{input.[this one has spaces]}}
{{input.[anotherone].[0]}}

<!-- Prettier 3.1 -->
{{input.funky<api!response}}
{{input.this one has spaces}}
{{input.anotherone.0}}

<!-- Prettier 3.2 -->
{{input.[funky<api!response]}}
{{input.[this one has spaces]}}
{{input.anotherone.[0]}}

GraphQL

Förbättra formateringen av GraphQL-unionstyper (#15870 av @ArchitGajjar)

# Input
union SearchResult = Conference| Festival | Concert | Venue | Conference| Festival | Concert | Venue

# Prettier 3.1
union SearchResult =
Conference
| Festival
| Concert
| Venue
| Conference
| Festival
| Concert
| Venue

# Prettier 3.2
union SearchResult =
| Conference
| Festival
| Concert
| Venue
| Conference
| Festival
| Concert
| Venue

API

Stöd absolut sökväg som plugin i konfigurationsfil (#15666 av @fisker)

// prettier.config.cjs
module.exports = {
plugins: [
// posix style
"/path/to/plugin.js",
// Windows style
"D:\\\\path\\to\\plugin.js",
// Use `require.resolve`
require.resolve("my-awesome-prettier-plugin"),
],
};

Fixa typdefinitioner för getFileInfo och getSupportInfo (#15854 av @auvred)

const plugin: Plugin = {};

prettier.getFileInfo("./file.ext", {
plugins: [plugin],
});

prettier.getSupportInfo({ plugins: [plugin], showDeprecated: true });

Diverse

Rättelse av felaktigt påstående i dokumentationen att cursorOffset är inkompatibelt med rangeStart/rangeEnd (#15750 av @ExplodingCabbage)

cursorOffset-alternativet har faktiskt varit kompatibelt med rangeStart/rangeEnd i över 5 år, tack vare arbete av @ds300. Dokumentationen för Prettier (inklusive CLI:s --help-text) fortsatte dock att felaktigt påstå motsatsen. Dokumentationen är nu korrigerad.