Prettier 3.7 : Amélioration de la cohérence de formatage et nouvelles fonctionnalités pour les plugins !
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Nous sommes ravis d'annoncer Prettier 3.7 ! Cette version se concentre sur l'amélioration de l'expérience TypeScript et Flow, notamment en alignant le formatage des classes et interfaces pour plus de cohérence et de prévisibilité. Nous souhaitons également recueillir votre avis sur le changement à venir concernant la logique d'impression incohérente de l'accolade ouvrant les corps de classe et d'interface.
Par ailleurs, nous avons corrigé de nombreux bugs, ajouté la prise en charge des nouvelles fonctionnalités d'Angular 21 et GraphQL 16.12, et implémenté la gestion du Front Matter pour Handlebars.
Pour les développeurs de plugins, nous avons ajouté de nouvelles API offrant un meilleur contrôle sur l'attachement des commentaires et la gestion des nœuds ignorés.
Si vous appréciez Prettier et souhaitez soutenir notre travail, envisagez de nous sponsoriser directement via notre OpenCollective ou en soutenant les projets dont nous dépendons. Merci pour votre soutien continu !
Principales fonctionnalités
TypeScript
Correction de l'impression incohérente entre les classes et interfaces (#18094, #18091, #18215 par @fisker)
Dans cette version, nous avons fortement amélioré la cohérence entre le formatage des classes et interfaces. Auparavant, ces deux structures similaires étaient imprimées différemment, créant des incohérences visuelles. Nous avons harmonisé leurs règles de formatage pour un résultat plus prévisible et plus propre.
L'indentation supplémentaire des paramètres de type dans les classes a été supprimée
// Input
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
extends A, B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
// Prettier 3.6
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
> extends A,
B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
// Prettier 3.7
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
extends A, B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
Alignement de l'impression des héritages d'interface avec les classes
// Input
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
// Prettier 3.6
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>,
PointOverlayMixins<ES>,
LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
// Prettier 3.7
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
Alignement de l'impression des héritages uniques avec les superclasses
// Input
class ExtendsLongOneWithGenerics
extends
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
class ExtendsLongOneWithGenerics
implements
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
interface ExtendsLongOneWithGenerics
extends
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
// Prettier 3.6
class ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
class ExtendsLongOneWithGenerics
implements
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
interface ExtendsLongOneWithGenerics
extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
// Prettier 3.7
class ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
class ExtendsLongOneWithGenerics implements Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
interface ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
Logique d'impression incohérente de l'accolade ouvrant les corps de classe et d'interface
Dans Prettier v2.3, pour améliorer la séparation visuelle entre l'en-tête et le corps d'une classe, nous avons commencé à imprimer l'accolade d'ouverture { du corps de la classe sur une nouvelle ligne lorsque la classe possède plusieurs héritages.
// Prettier 2.2
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong {
property: string;
}
// Prettier 2.3
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong
{
property: string;
}
Cependant, ce changement ne satisfait pas tout le monde.
Dites-nous ce que vous pensez de l'application de ce changement aux interfaces en laissant un commentaire sur cette issue.
Si vous avez une meilleure solution pour ce problème, nous serons ravis d'en discuter.
À moins qu'une meilleure solution n'apparaisse, nous alignerons l'impression du corps des interfaces sur celle des classes dans Prettier v4.
// Input
declare class loooooooooooooooooooong
implements looooooooooooooooooong, loooooooooooooooooooong {
property: string;
}
interface loooooooooooooooooooong
extends looooooooooooooooooong, loooooooooooooooooooong {
property: string;
}
// Prettier 3.7
declare class loooooooooooooooooooong
implements looooooooooooooooooong, loooooooooooooooooooong
{
property: string;
}
interface loooooooooooooooooooong
extends looooooooooooooooooong, loooooooooooooooooooong { // <-- This
property: string;
}
Ces changements affectent également la syntaxe Flow
Autres changements
JavaScript
Autoriser la répartition des attributs d'import sur plusieurs lignes (#17329 par @fisker)
// Input
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with {
BABEL_8_BREAKING: "false",
USE_ESM: "true", IS_STANDALONE: "false" };
// Prettier 3.6
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with { BABEL_8_BREAKING: "false", USE_ESM: "true", IS_STANDALONE: "false" };
// Prettier 3.7
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with {
BABEL_8_BREAKING: "false",
USE_ESM: "true",
IS_STANDALONE: "false",
};
Ajout de la prise en charge de la proposition "Discard Bindings" (#17708 par @fisker)
La proposition de stage 2 "Discard Bindings" est désormais prise en charge via Babel. Consultez notre politique sur la syntaxe non standardisée avant d'utiliser cette fonctionnalité syntaxique proposée avec Prettier.
const [void] = x;
const {x:void} = x;
Correction du format incohérent des commentaires (#17723 par @fisker)
// Input
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.6 (--parser=typescript --experimental-operator-position=start)
if (
true
&& // This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.6 (--parser=babel --experimental-operator-position=start)
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.7
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
Ajout de fonctions de test Playwright supplémentaires (#17876 par @BPScott)
Prettier évitait déjà de modifier l'indentation des fonctions de test lorsqu'on y ajoute .skip.
Il prend désormais également en compte les fonctions Playwright test.fixme, test.describe.skip et test.describe.fixme de manière similaire à test.skip.
// Input
test.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe.skip("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
// Prettier 3.6
test.fixme(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
test.describe.skip(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
test.describe.fixme(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
// Prettier 3.7
test.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe
.skip("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe
.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
Éviter les sauts de ligne dans {import,require.resolve,require.resolve.paths,import.meta.resolve}() avec des noms de modules longs (#17882, #17908 par @kovsu & @fisker)
// Input
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b = require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const c = require.resolve.paths("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const d = await import("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module")
const e = import.meta.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
// Prettier 3.6
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b = require.resolve(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
const c = require.resolve.paths(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
const d = await import(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module"
);
const e = import.meta.resolve(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
// Prettier 3.7
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b =
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const c = require.resolve
.paths("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const d =
await import("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const e = import.meta
.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
Amélioration de la gestion des commentaires dans les instructions conditionnelles (#17998 par @fisker)
// Input
if (foo) // comment
{
doThing();
} else // comment for else
{
doSomethingElse();
}
// Prettier 3.6
if (foo) {
// comment
doThing();
} // comment for else
else {
doSomethingElse();
}
// Prettier 3.7
if (foo) // comment
{
doThing();
} else // comment for else
{
doSomethingElse();
}
Amélioration des appels require() avec commentaires (#18037 par @fisker)
// Input
require(
// Comment
"foo"
);
// Prettier 3.6
require(// Comment
"foo");
// Prettier 3.7
require(
// Comment
"foo",
);
Suppression de l'indentation dans les expressions logiques des appels Boolean() (#18087 par @kovsu)
Réduit les différences lors du changement d'une condition à sa valeur opposée, ou lors de la conversion entre !! et Boolean().
// Input
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
// Prettier 3.6
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition,
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
// Prettier 3.7
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
Correction de la gestion des commentaires pour les boucles for (#18099 par @fisker, @sosukesuzuki)
// Input
for (x of y)
// Comment
bar();
// Prettier 3.6
// Comment
for (x of y) bar();
// Prettier 3.7
for (x of y)
// Comment
bar();
Amélioration de l'affichage des commentaires autour des instructions vides (#18108 par @fisker)
// Input
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index ++
) /* No op */;
// Prettier 3.6
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index++ /* No op */
);
// Prettier 3.7
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index++
) /* No op */ ;
Correction de l'affichage incohérent des commentaires entre méthodes de classe et méthodes d'objet (#18147 par @fisker)
// Input
class x {
method() // Class method
{
return 1
}
}
const object = {
method() // Object method
{
return 1
}
}
// Prettier 3.6
class x {
method() { // Class method
return 1;
}
}
const object = {
method() {
// Object method
return 1;
},
};
// Prettier 3.7
class x {
method() {
// class method
return 1;
}
}
const object = {
method() {
// object method
return 1;
},
};
Ajout des parenthèses manquantes pour les opérateurs binaires (#18163 par @fs0414)
// Input
1 << (bit % 8);
1 >> (bit - 8);
// Prettier 3.6
1 << bit % 8;
1 >> (bit - 8);
// Prettier 3.7
1 << (bit % 8);
1 >> (bit - 8);
Correction des sauts de ligne incohérents dans les littéraux de tableaux (#18172 par @Dunqing, @fisker)
// Input
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides___(-1, -1), [1]);
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides(-1, -1), [1, 2]);
// Prettier 3.6
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides___(-1, -1), [
1,
]);
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides(-1, -1),
[1, 2],
);
// Prettier 3.7
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides___(-1, -1),
[1],
);
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides(-1, -1),
[1, 2],
);
Correction de l'affichage incohérent des expressions logiques (#18205 par @fisker)
// Input
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b
);
// Prettier 3.6
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
// Prettier 3.7
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
Correction des différences d'affichage entre CallExpression et NewExpression (#18206 par @fisker)
// Input
TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection
)?.promptType
)
new TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection
)?.promptType
)
// Prettier 3.6
TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
);
new TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection,
)?.promptType,
);
// Prettier 3.7
TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
);
new TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
)
Suppression des parenthèses redondantes autour des éléments JSX (#18243 par @fisker)
// Input
new A(
<div>
<div></div>
</div>
)
// Prettier 3.6
new A(
(
<div>
<div></div>
</div>
),
);
// Prettier 3.7
new A(
<div>
<div></div>
</div>,
);
Amélioration du formatage des expressions logiques comme appelées dans les expressions new (#18245 par @fisker)
// Input
a = new (
a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition
)();
// Prettier 3.6
a = new (a_long_long_long_long_condition ||
a_long_long_long_long_condition ||
a_long_long_long_long_condition)();
// Prettier 3.7
a = new (
a_long_long_long_long_condition ||
a_long_long_long_long_condition ||
a_long_long_long_long_condition
)();
Suppression des lignes vides dans les boucles for sans clause "update" (#18300 par @fisker)
// Input
for ( let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;i < len;) {}
// Prettier 3.6
for (
let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;
i < len;
) {}
// Prettier 3.7
for (
let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;
i < len;
) {}
Amélioration du formatage des classes parentes (#18325 par @fisker)
// Input
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule.RuleModule {};
// Prettier 3.6
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule
.RuleModule {}
// Prettier 3.7
class EnsureNoDisposablesAreLeakedInTestSuiteSuite
extends eslint.Rule.RuleModule {}
TypeScript
Correction du placement incorrect des commentaires après les flèches (#17421 par @o-m12a, @t-mangoe)
// Input
export const test = (): any => /* first line
second line
*/
null;
// Prettier 3.6
export const test = (): any /* first line
second line
*/ => null;
// Prettier 3.6 (Second format)
SyntaxError: Unexpected token (1:22)
> 1 | export const test = (): any /* first line
| ^
2 | second line
3 | */ => null;
4 |
// Prettier 3.7
export const test = (): any =>
/* first line
second line
*/
null;
Ajout des parenthèses manquantes pour les fonctions fléchées dans les expressions d'instanciation (#17724 par @fisker)
// Input
void (<_T extends never>() => {})<never>;
// Prettier 3.6
void <_T extends never>() => {}<never>;
// Prettier 3.7
void (<_T extends never>() => {})<never>;
Correction du formatage des TSMappedType (#17785 par @fisker)
// Input (--parser=babel-ts)
export type A = B extends { C?: { [D in infer E]?: F } } ? G : H
// Prettier 3.6
TypeError: Cannot read properties of undefined (reading 'startsWith')
// Prettier 3.7
export type A = B extends { C?: { [D in infer E]?: F } } ? G : H;
Ajout de la virgule finale dans les options des TSImportType (#17798 par @fisker)
La virgule finale dans les attributs des types d'import n'était pas autorisée avant TypeScript v5.9, mais le bug est désormais corrigé.
// Input
type A = import("foo", {
with:{
type:'json',
} // <- Should be a comma here
})
// Prettier 3.6
type A = import("foo", {
with: {
type: "json",
} // <- Should be a comma here
});
// Prettier 3.7
type A = import("foo", {
with: {
type: "json",
}, // <- Should be a comma here
});
Amélioration du formatage des require() CommonJS avec commentaires (#18035 par @fisker)
// Input
import foo = require(
// Comment
"foo"
);
// Prettier 3.6
import foo = require(// Comment
"foo");
// Prettier 3.7
import foo = require(
// Comment
"foo"
);
Saut de ligne après le = dans les paramètres de type (#18043 par @fisker)
// Input
export type OuterType2<
LongerLongerLongerLongerInnerType = LongerLongerLongerLongerLongerLongerLongerLongerOtherType
> = { a: 1 };
// Prettier 3.6
export type OuterType2<
LongerLongerLongerLongerInnerType = LongerLongerLongerLongerLongerLongerLongerLongerOtherType,
> = { a: 1 };
// Prettier 3.7
export type OuterType2<
LongerLongerLongerLongerInnerType =
LongerLongerLongerLongerLongerLongerLongerLongerOtherType,
> = { a: 1 };
Suppression des lignes vides inattendues avant les types union (#18109 par @jspereiramoura, @fisker)
// Input
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.6
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.7
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
Cette modification affecte également la syntaxe Flow
Correction des différences d'impression des commentaires entre les parseurs typescript et flow (#18110 par @fisker)
// Input
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
& Fooo1000
& Baz2000
& BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.6 (--parser=typescript)
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.6 (--parser=flow)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: Fooo1000 & // Comment
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.7 (Same output for `--parser=typescript` and `--parser=flow`)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
Ajout des points-virgules manquants avant les signatures d'appel (#18118 par @fisker)
// Input
interface A {
foo;
<T>(): T;
}
type B = {
foo;
<T>(): T;
}
// Prettier 3.6 (--no-semi, first format)
interface A {
foo
<T>(): T
}
type B = {
foo
<T>(): T
}
// Prettier 3.6 (--no-semi, second format)
interface A {
foo<T>(): T
}
type B = {
foo<T>(): T
}
// Prettier 3.7
interface A {
foo;
<T>(): T
}
type B = {
foo;
<T>(): T
}
Harmonisation de l'impression des as const entre les parseurs Flow et TypeScript (#18161 par @fisker)
// Input
1 as /* comment */ const;
// Prettier 3.6 (--parser=typescript)
1 as /* comment */ const;
// Prettier 3.6 (--parser=flow)
1 /* comment */ as const;
// Prettier 3.7 (Same output for `--parser=typescript` and `--parser=flow`)
1 /* comment */ as const;
Correction du placement des commentaires autour des expressions as/satisfies (#18162 par @fisker)
// Input
1 as /*
comment
*/
const;
// Prettier 3.6 (First format)
1 /*
comment
*/ as const;
// Prettier 3.6 (Second format)
SyntaxError: Unexpected keyword or identifier. (3:4)
1 | 1 /*
2 | comment
> 3 | */ as const;
| ^
4 |
// Prettier 3.7
1 as const /*
comment
*/;
Correction de l'alignement erroné des types union (#18165 par @fisker)
// Input
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
// Prettier 3.6
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
// Prettier 3.7
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
Suppression de la ligne vide superflue dans les types union (#18197 par @Dunqing)
// Input
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.6
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.7
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
Flow
Ajout du support basique pour la syntaxe "match" (#17681 par @fisker)
// Input
const e = match (a) {
1 => true,
'foo' => false,
2 => {obj: 'literal'},
};
// Prettier 3.6
SyntaxError: Unexpected token `{`, expected the token `;` (1:21)
> 1 | const e = match (a) {
| ^
2 | 1 => true,
3 | 'foo' => false,
4 | 2 => {obj: 'literal'},
// Prettier 3.7
const e = match (a) {
1 => true,
"foo" => false,
2 => { obj: "literal" },
};
Prise en charge des types opaques avec bornes inférieures et supérieures (#17792 par @SamChou19815)
// Input
opaque type Counter super empty extends Box<T> = Container<T>;
opaque type Counter super Box<T> = Container<T>;
declare opaque type Counter super empty extends Box<T>;
declare opaque type Counter super Box<T>;
// Prettier 3.6
SyntaxError: Unexpected identifier, expected the token `=` (1:21)
// Prettier 3.7
opaque type Counter super empty extends Box<T> = Container<T>;
opaque type Counter super Box<T> = Container<T>;
declare opaque type Counter super empty extends Box<T>;
declare opaque type Counter super Box<T>;
CSS
Gestion des sélecteurs d'attribut avec drapeaux de sensibilité à la casse (#17841, #17865 par @kovsu)
/* Input */
[type=a s],
[type=a S],
[type=a I] {
list-style-type: lower-alpha;
}
/* Prettier 3.6 */
[type="a s"],
[type="a S"],
[type="a I"] {
list-style-type: lower-alpha;
}
/* Prettier 3.7 */
[type="a" s],
[type="a" S],
[type="a" I] {
list-style-type: lower-alpha;
}
Correction du plantage lors du formatage des propriétés personnalisées spéciales (#17899 par @fisker)
/* Input */
:root {
--l: , #000;
}
/* Prettier 3.6 */
TypeError: Cannot read properties of undefined (reading 'value')
/* Prettier 3.7 */
:root {
--l: , #000;
}
Correction de la conversion incorrecte en minuscules des sélecteurs dans les modules CSS (#17929 par @kovsu)
/* Input */
:export {
nest: {
myColor: blue;
}
myColor: red;
}
/* Prettier 3.6 */
:export {
nest: {
mycolor: blue;
}
myColor: red;
}
/* Prettier 3.7 */
:export {
nest: {
myColor: blue;
}
myColor: red;
}
Correction du formatage des sélecteurs CSS contenant // (#17938 par @kovsu)
/* Input */
a[href="http://example.com"] {
color: red;
}
/* Prettier 3.6 */
a[href="http://example.com"]
{
color: red;
}
/* Prettier 3.7 */
a[href="http://example.com"] {
color: red;
}
Suppression de l'espace inattendu entre taille de police et hauteur de ligne (#18114 par @kovsu)
/* Input */
a {
font: var(--size)/1;
}
/* Prettier 3.6 */
a {
font: var(--size) / 1;
}
/* Prettier 3.7 */
a {
font: var(--size)/1;
}
Correction de l'indentation excessive pour les valeurs séparées par des virgules en CSS après un commentaire de bloc (#18228 par @seiyab)
/* Input */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
/* Prettier 3.6 */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
/* Prettier 3.7 */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
SCSS
Correction du problème d'espace des parenthèses dans les arguments de mixin (#17836 par @kovsu)
// Input
.foo {
@include bar('A (B)');
}
// Prettier 3.6
.foo {
@include bar('A( B)');
}
// Prettier 3.7
.foo {
@include bar('A (B)');
}
Correction du formatage des valeurs séparées par des espaces (#17903 par @kovsu)
// Input
.foo {
@include transition(min-height ($spacer/2) ease-in-out);
}
// Prettier 3.6
.foo {
@include transition(min-height($spacer/2) ease-in-out);
}
// Prettier 3.7
.foo {
@include transition(min-height ($spacer/2) ease-in-out);
}
Less
Correction de la conversion incorrecte en minuscules des noms de variables (#17820 par @kovsu)
// Input
@fooBackground:line-gradient(#f00);
a {
background: @fooBackground;
}
// Prettier 3.6
@foobackground:line-gradient (#f00);
a {
background: @fooBackground;
}
// Prettier 3.7
@fooBackground: line-gradient(#f00);
a {
background: @fooBackground;
}
Maintien de la compacité des accesseurs de propriétés/variables (#17983 par @kovsu)
// Input
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px) [ @result ];
}
// Prettier 3.6
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px) [ @result];
}
// Prettier 3.7
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px)[@result];
}
HTML
Prise en charge du formatage de l'attribut allow des éléments iframe (#17879 par @kovsu)
<!-- Input -->
<iframe allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
<!-- Prettier 3.6 -->
<iframe allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
<!-- Prettier 3.7 -->
<iframe
allow="
layout-animations 'none';
unoptimized-images 'none';
oversized-images 'none';
sync-script 'none';
sync-xhr 'none';
unsized-media 'none';
"
></iframe>
Formatage des gestionnaires d'événements inline (#17909 par @kovsu)
<!-- Input -->
<button
type="button"
onclick="console .log( 'Hello, this is my old-fashioned event handler!')"
>Press me</button>
<!-- Prettier 3.6 -->
<button
type="button"
onclick="console .log( 'Hello, this is my old-fashioned event handler!')"
>
Press me
</button>
<!-- Prettier 3.7 -->
<button
type="button"
onclick="console.log('Hello, this is my old-fashioned event handler!')"
>
Press me
</button>
Angular
Prise en charge d'Angular 21 (#17722, #18294 par @fisker)
Angular 20.1 a ajouté la prise en charge de nouveaux opérateurs d'assignation. Angular 21 a ajouté la prise en charge des expressions régulières.
<!-- Input -->
<b (click)="
a ??= b">{{ /\d+/g}}</b>
<!-- Prettier 3.6 -->
<b
(click)="
a ??= b"
>{{ /\d+/g}}</b
>
<!-- Prettier 3.7 -->
<b (click)="a ??= b">{{ /\d+/g }}</b>
Correction de la duplication des commentaires dans les interpolations (#17862 par @fisker)
<!-- Input -->
{{a() // comment}}
<!-- Prettier 3.6 -->
{{ a(// comment) // comment }}
<!-- Prettier 3.7 -->
{{
a() // comment
}}
Correction du formatage des "non-null assertions" (#18047 par @fisker)
<!-- Input -->
{{ foo?.bar!.baz }}
<!-- Prettier 3.6 -->
{{ (foo?.bar)!.baz }}
<!-- Prettier 3.7 -->
{{ foo?.bar!.baz }}
Ember / Handlebars
Ajout du support Front Matter pour Handlebars (#17781 par @Codezilluh)
Le Front Matter peut désormais être utilisé dans Handlebars.
---
title: My page title
keywords:
- word
- other word
---
<h1>{{title}}</h1>
<ul>
{{#each keywords}}
<li>{{this}}</li>
{{/each}}
</ul>
Préservation de la syntaxe else if pour les helpers personnalisés (#17856 par @kovsu)
{{! Input }}
{{#animated-if this.foo}}
foo content
{{else if (this.bar)}}
bar content
{{/animated-if}}
{{! Prettier 3.6 }}
{{#animated-if this.foo}}
foo content
{{else}}{{#if (this.bar)}}
bar content
{{/if}}{{/animated-if}}
{{! Prettier 3.7 }}
{{#animated-if this.foo}}
foo content
{{else if (this.bar)}}
bar content
{{/animated-if}}
Suppression des lignes vides supplémentaires dans les balises <style> (#18065 par @kovsu, @fisker)
{{! Input }}
<style>
#foo {
color: red;
}
</style>
{{! Prettier 3.6 (--html-whitespace-sensitivity=ignore) }}
<style>
#foo {
color: red;
}
</style>
{{! Prettier 3.7 (--html-whitespace-sensitivity=ignore) }}
<style>
#foo {
color: red;
}
</style>
Ne pas forcer les éléments à se rompre avec --html-whitespace-sensitivity=ignore (#18133 par @fisker)
{{! Input }}
<div> </div>
{{! Prettier 3.6 (--html-whitespace-ensitivity=ignore) }}
<div>
</div>
{{! Prettier 3.7 (--html-whitespace-ensitivity=ignore) }}
<div></div>
GraphQL
Prise en charge des "executable descriptions" (#18214 par @fisker)
# Input
"Description"
query {
node {
id
}
}
# Prettier 3.6
SyntaxError: Syntax Error: Unexpected description, descriptions are supported only on type definitions. (1:1)
> 1 | "Description"
| ^
2 | query {
3 | node {
4 | id
# Prettier 3.7
"Description"
query {
node {
id
}
}
Markdown
Amélioration de la mesure de la taille des emojis (#17813 par @seiyab)
Cette amélioration optimise l'alignement des tableaux dans tous les langages.
<!-- Input -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
<!-- Input -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
<!-- Prettier 3.7 -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
Inférence du parser TOML pour le Front Matter (#17965 par @kovsu)
Le Front Matter TOML peut être traité par le plugin approprié s'il est disponible. Fonctionne également pour les fichiers HTML et CSS.
Correction du formatage des emphases fortes (#18010 par @yin1999)
Il s'agit d'un correctif complémentaire pour #17143, où la PR originale ne pouvait pas déterminer si les contenus des côtés gauche et droit étaient tous deux des mots.
<!-- Input -->
1***2***3
1**_2_**3
<!-- Prettier 3.6 -->
1**_2_**3
1**_2_**3
<!-- Prettier 3.7 -->
1***2***3
1***2***3
MDX
Correction du parsing des import et export (#17996 par @kovsu & @fisker)
{/* Input */}
- import is a word in lists
- export is a word in lists, too!
{/* Prettier 3.6 */}
- import is a word in list
s
- export is a word in lists, too
!
{/* Prettier 3.7 */}
- import is a word in lists
- export is a word in lists, too!
YAML
Préservation des lignes vides entre les map et les commentaires (#17843 par @kovsu)
# Input
only: issues
# Comment
# Prettier 3.6
only: issues
# Comment
# Prettier 3.7
only: issues
# Comment
Préserver le marqueur explicite de fin de document (#18296 par @fisker)
# Input
a: a
---
b: b
...
c: c
...
---
d: d
# Prettier 3.6
a: a
---
b: b
---
c: c
---
d: d
# Prettier 3.7
a: a
---
b: b
...
c: c
...
---
d: d
Utiliser un style de clé explicite pour les clés de mapping Flow avec des commentaires en suffixe (#18324 par @kovsu, @fisker)
# Input
{ "foo" # comment
:bar }
# Prettier 3.6
{ "foo": bar } # comment
# Prettier 3.7
{ ? "foo" # comment
: bar }
API
Permettre à plugin.parser.preprocess() de renvoyer une Promise (#17679 par @fisker)
Alignement avec plugin.printer.preprocess() qui permet déjà de renvoyer une Promise.
Nous recommandons toujours de déplacer votre travail asynchrone dans plugin.parser.parse(), qui permet déjà de renvoyer une Promise. Nous pourrions supprimer le support de plugin.parser.preprocess() à l'avenir.
Permettre à AstPath#call() d'accéder aux propriétés nullish (#17860 par @fisker)
Auparavant, pour vérifier un nœud enfant potentiellement inexistant, nous devions d'abord nous assurer de son existence.
const isFoo = path.call(() => path.node?.type === "Foo", "foo", "bar");
// Uncaught TypeError: Cannot read properties of undefined (reading 'bar')
Nous devions
const isFoo =
path.node.foo?.bar &&
path.call(() => path.node?.type === "Foo", "foo", "bar");
Depuis Prettier 3.7, l'accès aux propriétés nullish ne génère plus d'erreurs.
Transmettre les ancêtres à plugin.printer.canAttachComment() (#18055 par @fisker)
Cela empêche d'attacher des commentaires à un enfant spécifique d'un nœud.
Par exemple dans ce code JavaScript const object = {property};, le nœud Identifier (property) apparaît à la fois comme Property.key et Property.value dans l'AST. Il ne peut être imprimé qu'une seule fois - si le commentaire est attaché à l'enfant non imprimable, il sera perdu.
Les plugins peuvent désormais éviter cela en ajoutant un canAttachComment comme suit :
export const canAttachComment = (node, [parent]) =>
!(
parent?.type === "Property" &&
parent.shorthand &&
parent.key === node &&
parent.key !== parent.value
);
export const print = (path, options, print) => {
const { node } = path;
switch (node.type) {
case "Property":
if (node.shorthand) {
return print("value");
}
// ...
}
};
Ajouter la prise en charge de plugin.printer.printPrettierIgnored() (#18070 par @fisker)
Pour un nœud avec un commentaire prettier-ignore, Prettier imprime le texte du nœud directement. Cependant, cela peut causer des problèmes, par exemple si le nœud doit être mis entre parenthèses ou s'il doit imprimer un point-virgule initial pour éviter un problème ASI en mode --no-semi.
Depuis Prettier 3.7, les plugins peuvent ajouter une fonction printPrettierIgnored() à l'imprimante pour personnaliser le processus d'impression des nœuds prettier-ignore. Cette fonction utilise exactement la même signature que plugin.printer.print().
Permettre aux plugins de fournir un imprimant estree (#18072 par @fisker)
Auparavant, si un plugin souhaitait créer une imprimante estree produisant un code différent de l'imprimante intégrée, il devait fournir à la fois parsers et printers. Prettier 3.7 permet désormais de créer un plugin qui ne fournit qu'une imprimante estree.
CLI
Éviter la création du répertoire node_modules/.cache/ lorsque --cache n'est pas activé (#18124 by @chiawendt)
L'exécution de prettier . sans --cache ne crée plus de répertoire vide node_modules/.cache/.
