Aller au contenu principal

Prettier 2.3 : Des assignations cohérentes, des clés courtes sans saut de ligne, et Handlebars officiel

· 34 minutes de lecture
Traduction Bêta Non Officielle

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 →

Cette version se concentre sur la correction de problèmes de longue date dans le formateur JavaScript. Attention : malheureusement, reformater un projet avec la nouvelle version pourrait entraîner un diff assez important. Si vous n'utilisez pas ignoreRevsFile pour masquer ces changements massifs de git blame, c'est peut-être le moment d'y penser.

Une étape remarquable est la sortie tant attendue du formateur Ember / Handlebars. Il devrait s'agir du dernier formateur inclus directement dans la bibliothèque principale. À l'avenir, pour des raisons de durabilité, les langages devraient être ajoutés uniquement via des plugins.

Nous remercions nos contributeurs financiers : Salesforce, Indeed, Frontend Masters, Airbnb, Shogun Labs, Skyscanner, Konstantin Pschera, et bien d'autres qui nous aident à continuer. Si vous appréciez Prettier et souhaitez soutenir notre travail, rendez-vous sur notre OpenCollective. Pensez également à soutenir les projets dont Prettier dépend, tels que typescript-eslint, remark, et Babel.

La plupart des changements dans cette version sont le fruit du travail acharné de Fisker Cheung, Georgii Dolzhykov, et Sosuke Suzuki, ainsi que de nombreux autres contributeurs.

Et juste un rappel : lors de l'installation ou de la mise à jour de Prettier, il est fortement recommandé de spécifier la version exacte dans package.json : "2.3.0", et non "^2.3.0".

Principales fonctionnalités

JavaScript

Formater les assignations de manière plus cohérente (#10222, #10643, #10672 par @thorn0; #10158 par @sosukesuzuki)

Auparavant, Prettier avait beaucoup de difficultés à déterminer comment couper les lignes dans les assignations. Par exemple, les parties droites longues restaient souvent non coupées. Ce n'est plus le cas.

// Prettier 2.2
aParticularlyLongAndObnoxiousNameForIllustrativePurposes = anotherVeryLongNameForIllustrativePurposes;

aParticularlyLongAndObnoxiousNameForIllustrativePurposes = "a very long string for illustrative purposes"
.length;

someReallyLongThingStoredInAMapWithAReallyBigName[
pageletID
] = _someVariableThatWeAreCheckingForFalsiness
? Date.now() - _someVariableThatWeAreCheckingForFalsiness
: 0;

class x {
private readonly rawConfigFromFile$: BehaviorSubject<any> = new BehaviorSubject(
notRead
);
}

// Prettier 2.3
aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
anotherVeryLongNameForIllustrativePurposes;

aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
"a very long string for illustrative purposes".length;

someReallyLongThingStoredInAMapWithAReallyBigName[pageletID] =
_someVariableThatWeAreCheckingForFalsiness
? Date.now() - _someVariableThatWeAreCheckingForFalsiness
: 0;

class x {
private readonly rawConfigFromFile$: BehaviorSubject<any> =
new BehaviorSubject(notRead);
}

Empêcher le retour à la ligne pour les propriétés d'objet avec des clés courtes (#10335 par @thorn0)

Les retours à la ligne après des noms de propriétés courts dans les littéraux d'objet semblent souvent non naturels. Même lorsqu'un tel retour à la ligne procure un gain de longueur de ligne de 1 ou 2 caractères, il semble rarement justifié. Prettier 2.3 évite les retours à la ligne après des noms de propriétés plus courts que tabWidth + 3 – par exemple, 5 caractères dans la configuration par défaut, ou 7 caractères avec tabWidth: 4. Cette heuristique pourra être révisée dans les futures versions.

// Prettier 2.2
const importantLink = {
url:
"https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about",
gitHubUrl:
"https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about",
};

// Prettier 2.3
const importantLink = {
url: "https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about",
gitHubUrl:
"https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about",
};

Ember / Handlebars

Faire passer le support Handlebars de l'alpha à la version stable (#10290 par @dcyriller & @thorn0)

Tout a commencé en 2017. Le support de Handlebars était présent dans Prettier depuis un moment, mais n'avait jamais été officiellement publié car il n'était pas vraiment prêt. Son statut est passé d'"alpha" à "expérimental", puis à "bêta", et si vous consultez les anciennes notes de version, vous constaterez qu'après "bêta", il est redevenu "alpha" d'une manière ou d'une autre...

Quoi qu'il en soit, c'est enfin chose faite : Prettier peut désormais formater officiellement les templates HTML avec Handlebars ! 🎉

Il utilise Glimmer, le parseur Handlebars d'Ember, ce qui devrait garantir la conformité avec les spécifications HTML grâce à l'équipe Ember.

L'option --html-whitespace-sensitivity est prise en charge et vaut strict par défaut, ce qui signifie que Prettier respectera toujours la présence ou l'absence d'espaces autour des balises, considérant comme risqué d'ajouter des espaces là où il n'y en avait pas (et vice-versa), car cela pourrait affecter le rendu du document dans le navigateur. La valeur css n'est pas encore prise en charge (traitée comme strict pour l'instant).

Cette fonctionnalité s'appelle "Ember / Handlebars" et non simplement "Handlebars" car Glimmer ne prend pas en charge certaines syntaxes et cas d'usage de Handlebars. Cela vient du fait que Handlebars, étant un moteur de templates (préprocesseur), ignore la syntaxe sous-jacente du contenu traité, tandis que Glimmer parse simultanément deux syntaxes - HTML et Handlebars - et combine le résultat en un arbre unique que Prettier peut imprimer. Cela signifie que Prettier ne formatera pas les fichiers Handlebars qui ne peuvent être parsés en un tel arbre, soit parce que la syntaxe sous-jacente n'est pas du HTML, soit parce que les directives et balises se chevauchent de manière non représentable dans un arbre (ex: {{#if foo}}<div>{{/if}). Malgré ces restrictions, le formateur reste suffisamment utile pour les utilisateurs non-Ember de Handlebars. Concernant la syntaxe non supportée par Ember, il y a de bonnes chances qu'elle soit prise en charge dans les futures versions de Prettier, car Glimmer utilise un parseur Handlebars complet sous le capot.

Les fichiers avec les extensions .hbs et .handlebars sont reconnus comme Handlebars par défaut. Pour d'autres extensions, l'option --parser avec la valeur glimmer doit être spécifiée - par exemple via la ligne de commande ou, mieux encore, par des [surcharges de configuration].

Découvrez le formateur en action sur le playground !

Améliorations du formatage

JavaScript

Affiner le formatage des fonctions fléchées curryfiées (#9992, #10543 par @sosukesuzuki & @thorn0)

// Prettier 2.2
const currying = (argument1) => (argument2) => (argument3) => (argument4) => (
argument5
) => (argument6) => foo;

// Prettier 2.3
const currying =
(argument1) =>
(argument2) =>
(argument3) =>
(argument4) =>
(argument5) =>
(argument6) =>
foo;

Améliorer le formatage des appels de React Hooks (#10238 par @sosukesuzuki)

// Prettier 2.2
const { firstName, lastName } = useMemo(() => parseFullName(fullName), [
fullName,
]);

// Prettier 2.3
const { firstName, lastName } = useMemo(
() => parseFullName(fullName),
[fullName]
);

Améliorer la séparation visuelle entre l'en-tête et le corps dans les classes avec des en-têtes multilignes (#10085 par @sosukesuzuki)

// Prettier 2.2
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong {
property: string;
}

// Prettier 2.3
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong
{
property: string;
}

Formatage concis des tableaux contenant uniquement des nombres (#10106, #10160 par @thorn0)

Bien qu'en général Prettier évite ce type de formatage car il n'est pas optimisé pour les diffs, dans ce cas particulier nous avons estimé que les bénéfices l'emportaient sur les risques.

Si au moins un élément possède un commentaire en ligne (// ...) sur la même ligne, le formatage concis n'est pas appliqué. En revanche, les commentaires placés sur des lignes séparées n'ont pas cet effet et - tout comme les lignes vides - peuvent être utilisés pour le regroupement logique.

// Input
const lazyCatererNumbers = [1, 2, 4, 7, 11, 16, 22, 29, 37, 46,

// n > 10
56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, 352, 379, 407, 436, 466,
497, 529, 562, 596, 631, 667, 704, 742, 781,
// n > 40
821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379];

// Prettier 2.2
const lazyCatererNumbers = [
1,
2,
4,
7,
11,
16,
22,
29,
37,
// ... ✂ 46 lines ✂ ...
1379,
];

// Prettier 2.3
const lazyCatererNumbers = [
1, 2, 4, 7, 11, 16, 22, 29, 37, 46,

// n > 10
56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326,
352, 379, 407, 436, 466, 497, 529, 562, 596, 631, 667, 704, 742, 781,
// n > 40
821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379,
];

Améliorer le formatage des expressions await imbriquées dans les têtes des expressions d'appel et de membre (#10342 par @thorn0)

Bien que Prettier essaie d'être utile ici, merci de ne pas écrire du code comme cela. Ayez pitié de vos collègues et utilisez des variables intermédiaires.

// Input
const getAccountCount = async () =>
(await
(await (
await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME)
).findItem("My bookmarks")).getChildren()
).length

// Prettier 2.2
const getAccountCount = async () =>
(
await (
await (await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME)).findItem(
"My bookmarks"
)
).getChildren()
).length;

// Prettier 2.3
const getAccountCount = async () =>
(
await (
await (
await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME)
).findItem("My bookmarks")
).getChildren()
).length;

Améliorer le formatage des expressions do dans les appels de fonction (#10693 par @sosukesuzuki)

Les "expressions do" sont une proposition ECMAScript de stage 1.

// Prettier 2.2
expect(
do {
var bar = "foo";
bar;
}
).toBe("foo");

// Prettier 2.3
expect(do {
var bar = "foo";
bar;
}).toBe("foo");

Indentation cohérente pour les opérateurs conditionnels (#10187, #10266 par @sosukesuzuki)

// Prettier 2.2
const dotNotationMemberExpression = (callNode.parent?.type ===
AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent
).TSESTree.BinaryExpression;

const computedMemberExpression = (callNode.parent?.type ===
AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent)[TSESTree.BinaryExpression];

const callExpressionCallee = (callNode.parent?.type ===
AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent)(TSESTree.BinaryExpression);

const typeScriptAsExpression = (callNode.parent?.type ===
AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent) as TSESTree.BinaryExpression;

// Prettier 2.3
const dotNotationMemberExpression = (
callNode.parent?.type === AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent
).TSESTree.BinaryExpression;

const computedMemberExpression = (
callNode.parent?.type === AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent
)[TSESTree.BinaryExpression];

const callExpressionCallee = (
callNode.parent?.type === AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent
)(TSESTree.BinaryExpression);

const typeScriptAsExpression = (
callNode.parent?.type === AST_NODE_TYPES.ChainExpression
? callNode.parent.parent
: callNode.parent
) as TSESTree.BinaryExpression;

HTML

Formatage multiligne basé sur les préfixes pour l'attribut class (#7865 par @thorn0)

Le formatage des noms de classe HTML conservera désormais les classes sur une seule ligne jusqu'à ce que la limite de longueur de ligne soit atteinte ; à ce moment-là, les classes consécutives avec le même préfixe seront regroupées sur chaque ligne. Pour les frameworks de mise en page tels que Bootstrap et Tailwind CSS, qui ajoutent de nombreuses classes à un élément, ceci est important pour la lisibilité et la maintenabilité par rapport au comportement précédent (conserver toutes les classes sur une ligne) ou par exemple mettre chaque classe sur sa propre ligne.

<!-- Prettier 2.2 -->
<div
class="SomeComponent__heading-row d-flex flex-column flex-lg-row justify-content-start justify-content-lg-between align-items-start align-items-lg-center"
></div>

<!-- Prettier 2.3 -->
<div
class="
SomeComponent__heading-row
d-flex
flex-column flex-lg-row
justify-content-start justify-content-lg-between
align-items-start align-items-lg-center
"
></div>

Autres changements

JavaScript

Correction de l'instabilité des commentaires multiples sur la même ligne (#9672 par @fisker)

// Input
a;
/*1*//*2*/
/*3*/
b;

// Prettier 2.2
a; /*2*/
/*1*/ /*3*/
b;

// Prettier 2.2 (second format)
a; /*2*/ /*3*/
/*1*/ b;

// Prettier 2.3
a;
/*1*/ /*2*/
/*3*/
b;

Ne pas formater les nœuds se terminant juste avant rangeStart (#9704 par @fisker)

Auparavant, lors du formatage par plage, ces nœuds étaient considérés comme faisant partie de la plage ; désormais, ils sont exclus. Cela affecte d'autres langages pris en charge par la fonctionnalité de formatage par plage, pas seulement JavaScript.

// Input
foo = 1.0000;bar = 1.0000;baz=1.0000;
^^^^^^^^^^^^^ Range

// Prettier 2.2
foo = 1.0;
bar = 1.0;baz=1.0000;

// Prettier 2.3
foo = 1.0000;bar = 1.0;baz=1.0000;

Correction des commentaires dans la balise de fermeture JSX (#9711 par @fisker)

// Input
<a><// comment
/a>;

// Prettier 2.2
<a></// comment
a>;

// Prettier 2.3
<a></
// comment
a
>;

Correction de la détection incohérente des commentaires de langage (#9743 par @fisker)

Un commentaire /* HTML */ doit précéder directement un littéral de modèle pour que ce dernier soit reconnu comme du HTML dans du JS. Auparavant, le commentaire était reconnu à tort dans certains autres emplacements.

// Input
foo /* HTML */ = `<DIV>
</DIV>`;

// Prettier 2.2 (--parser=babel)
foo /* HTML */ = `<div></div>`;

// Prettier 2.2 (--parser=meriyah)
foo /* HTML */ = `<DIV>
</DIV>`;

// Prettier 2.3 (All JavaScript parsers)
foo /* HTML */ = `<DIV>
</DIV>`;

Correction du point-virgule supplémentaire ajouté aux directives ignorées (#9850 par @fisker)

// Input
// prettier-ignore
'use strict';

function foo() {
// prettier-ignore
"use strict";;
}

// Prettier 2.2
// prettier-ignore
'use strict';;

function foo() {
// prettier-ignore
"use strict";;
}

// Prettier 2.3
// prettier-ignore
'use strict';

function foo() {
// prettier-ignore
"use strict";
}

Correction de l'instabilité du formatage JSX avec U+3000 (#9866 par @fisker)

// Input
<p>
<span /> {this.props.data.title} <span />
//----- ^ U+3000 --------------- ^ U+3000
</p>

// Prettier 2.2
<p>
<span />
 {this.props.data.title} <span />
//----- ^ U+3000 --------------- ^ U+3000
</p>;

// Prettier 2.2 (second format)
<p>
<span /> {this.props.data.title} <span />
//----- ^ U+3000 --------------- ^ U+3000
</p>;

// Prettier 2.3
<p>
<span /> {this.props.data.title} <span />
//----- ^ U+3000 --------------- ^ U+3000
</p>;

Correction de l'erreur sur les expressions du type a(b => c => function (){}) (#10278 par @thorn0)

Régression depuis la version v2.2.0.

// Input
a(b => c => function (){})

// Prettier 2.2
TypeError: Cannot read property 'length' of undefined

// Prettier 2.3
a((b) => (c) => function () {});

Amélioration du formatage des décorateurs en ligne (#10296 par @fisker)

// Input
class Foo {
@decorator([]) bar() {}
@decorator(
[]
) baz() {}
}

// Prettier 2.2
class Foo {
@decorator([]) bar() {}
@decorator([])
baz() {}
}

// Prettier 2.3
class Foo {
@decorator([]) bar() {}
@decorator([]) baz() {}
}

Correction de la protection ASI pour les champs privés (#10334 par @thorn0)

// Input
class C {
#field = 'value';
["method"]() {}
}

// Prettier 2.2 (with --no-semi)
class C {
#field = "value"
["method"]() {}
}

// Prettier 2.3 (with --no-semi)
class C {
#field = "value";
["method"]() {}
}

Prise en charge de la proposition Module Blocks (#10417 par @sosukesuzuki, @thorn0)

Prise en charge du formatage pour la proposition Module Blocks Stage 2.

// Input
module { export let foo = "foo"; };

// Prettier 2.2
SyntaxError: Unexpected token, expected ";"

// Prettier 2.3
module {
export let foo = "foo";
};

Correction des parenthèses manquantes pour yield dans un pipeline (#10446 par @fisker)

// Input
function* f() {
return x |> (yield #);
}

// Prettier 2.2
function* f() {
return x |> yield #;
}

// Prettier 2.3
function* f() {
return x |> (yield #);
}

Amélioration de la tolérance aux erreurs de Babel (#10495 par @fisker, #9787 par @sosukesuzuki, #10065, #10322 par @thorn0)

Auparavant, la tolérance aux erreurs du parseur Babel était trop permissive, générant des structures AST que Prettier ne pouvait pas formater. La version 2.3 limite cette tolérance aux erreurs inoffensives (comme plusieurs déclarations const avec le même nom). Les autres erreurs sont désormais signalées comme des erreurs de syntaxe.

// Input
foo("a", , "b");

// Prettier 2.2
TypeError: Cannot read property 'type' of null

// Prettier 2.3
[error] stdin: SyntaxError: Argument expression expected. (1:10)
[error] > 1 | foo("a", , "b");
[error] | ^
// Input
const \u{20} = 1

// Prettier 2.2
const = 1;

// Prettier 2.3
[error] stdin: SyntaxError: Invalid Unicode escape (1:7)
[error] > 1 | const \u{20} = 1
[error] | ^ ^

Éviter le regroupement du dernier argument pour les tableaux numériques (#10517 par @thorn0)

Cas particulier supplémentaire pour les tableaux contenant uniquement des nombres.

// Input
instantiate(game, [
transform([-0.7, 0.5, 0]),
render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [1, 1, 0.3, 1]),
]);

// Prettier 2.2
instantiate(game, [
transform([-0.7, 0.5, 0]),
render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [
1,
1,
0.3,
1,
]),
]);

// Prettier 2.3
instantiate(game, [
transform([-0.7, 0.5, 0]),
render_colored_diffuse(
game.MaterialDiffuse,
game.Meshes["monkey_flat"],
[1, 1, 0.3, 1]
),
]);

Amélioration de la détection des appels AMD define (#10528 par @thorn0)

Prettier traite spécialement les appels AMD define pour éviter les sauts de ligne intempestifs. Désormais, seuls les appels define situés au niveau supérieur d'une fonction ou programme, avec des arguments conformes aux attentes AMD, sont formatés.

// Prettier 2.2
const someVariable = define("some string literal", anotherVariable, yetAnotherVariable);

// Prettier 2.3
const someVariable = define(
"some string literal",
anotherVariable,
yetAnotherVariable
);

Correction des commentaires prettier-ignore dupliqués (#10666 par @fisker)

// Input
foo = a.
// prettier-ignore
b;

// Prettier 2.2
foo =
// prettier-ignore
a.
// prettier-ignore
b;

// Prettier 2.3
foo = a.
// prettier-ignore
b;

Traitement des groupes conditionnels dans mapDoc (#10695 par @thorn0)

Cette correction résout notamment les problèmes de substitution dans du HTML-in-JS.

// Input
export default function include_photoswipe(
gallery_selector = ".my-gallery"
): string {
return /* HTML */ `
<script>
window.addEventListener("load", () =>
initPhotoSwipeFromDOM("${gallery_selector}")
);
</script>`;
}

// Prettier 2.2
export default function include_photoswipe(
gallery_selector = ".my-gallery"
): string {
return /* HTML */ ` <script>
window.addEventListener("load", () =>
initPhotoSwipeFromDOM("PRETTIER_HTML_PLACEHOLDER_0_13_IN_JS")
);
</script>`;
}

// Prettier 2.3
export default function include_photoswipe(
gallery_selector = ".my-gallery"
): string {
return /* HTML */ ` <script>
window.addEventListener("load", () =>
initPhotoSwipeFromDOM("${gallery_selector}")
);
</script>`;
}

Éviter l'expansion d'arguments générant du code cassé (#10712 par @thorn0)

// Input
glimseGlyphsHazardNoopsTieTie(({ a, b = () => {
console.log();
}}) => averredBathersBoxroomBuggyNurl());

// Prettier 2.2
glimseGlyphsHazardNoopsTieTie(({ a, b = () => {
console.log();
} }) => averredBathersBoxroomBuggyNurl());

// Prettier 2.3
glimseGlyphsHazardNoopsTieTie(
({
a,
b = () => {
console.log();
},
}) => averredBathersBoxroomBuggyNurl()
);

Correction des parenthèses manquantes autour d'async dans for-of (#10781 par @fisker)

Voir https://github.com/tc39/ecma262/issues/2034

// Input
for ((async) of []);

// Prettier 2.2
for (async of []);

// Prettier 2.2 (second format)
SyntaxError: Unexpected token, expected "=>" (1:15)
> 1 | for (async of []);

// Prettier 2.3
for ((async) of []);

Prise en charge de la proposition async do expressions (#10813 par @sosukesuzuki)

Voir https://github.com/tc39/proposal-async-do-expressions

// Input
const x = async do {
await requestAPI().json();
};

// Prettier 2.2
SyntaxError: Unexpected token, expected ";" (1:17)

// Prettier 2.3
const x = async do {
await requestAPI().json();
};

TypeScript

Correction des commentaires manquants dans MethodDefinition (#9872 par @fisker)

Problème spécifique au parseur typescript (le parseur babel-ts n'est pas concerné).

// Input
class Foo {
bar() /* bat */;
}

// Prettier 2.2
Error: Comment "bat" was not printed. Please report this error!

// Prettier 2.3
class Foo {
bar /* bat */();
}

Corriger les sauts de ligne inutiles dans les paramètres de déclaration de méthode typée (#10024 par @sosukesuzuki, #10357 par @thorn0)

// Input
type Foo = {
method(foo: "foo"): `
`
};

// Prettier 2.2
type Foo = {
method(
foo: "foo"
): `
`;
};

// Prettier 2.3
type Foo = {
method(foo: "foo"): `
`;
};

Imprimer les virgules finales dans les paramètres de type (#10109 par @sosukesuzuki, #10353 par @thorn0)

TypeScript prend en charge les virgules finales dans les paramètres de type depuis TypeScript 2.7 (sorti en janvier 2018). Prettier 2.3 les imprime si l'option trailingComma est définie sur all. Conservez cette option à la valeur par défaut plus conservatrice es5 si une compatibilité avec TypeScript 2.7 ou antérieur est nécessaire. Notez que TypeScript ne prend toujours pas en charge les virgules finales dans les arguments de type (instanciations de paramètres de type).

// Input
export class BaseSingleLevelProfileTargeting<
T extends ValidSingleLevelProfileNode,
> {
// ...
}

// Prettier 2.2
export class BaseSingleLevelProfileTargeting<
T extends ValidSingleLevelProfileNode
> {
// ...
}

// Prettier 2.3 with --trailling-comma=all
export class BaseSingleLevelProfileTargeting<
T extends ValidSingleLevelProfileNode,
> {
// ...
}

Permettre le regroupement des arguments qui sont des fonctions fléchées non concises avec annotations de type de retour (#10316 par @thorn0)

// Prettier 2.2
users.map(
(user: User): User => {
return user;
}
);

// Prettier 2.3
users.map((user: User): User => {
return user;
})

Corriger les parenthèses pour les assertions non-null (#10337 par @thorn0)

Les parenthèses nécessaires n'étaient parfois pas imprimées dans les expressions contenant des assertions non-null. Ce problème est résolu.

// Input
const myFunction2 = (key: string): number =>
({
a: 42,
b: 42,
}[key]!)

// Prettier 2.2 (invalid syntax)
const myFunction2 = (key: string): number =>
{
a: 42,
b: 42,
}[key]!;

// Prettier 2.3
const myFunction2 = (key: string): number =>
({
a: 42,
b: 42,
}[key]!);

Indenter les assertions de type dans les têtes d'expressions d'appel et de membres (#10341 par @thorn0)

// Input
const accountCount = (findItemInSection(BOOKMARKED_PROJECTS_SECTION_NAME,
"My bookmarks") as TreeItem).getChildren().length;

// Prettier 2.2
const accountCount = (findItemInSection(
BOOKMARKED_PROJECTS_SECTION_NAME,
"My bookmarks"
) as TreeItem).getChildren().length;

// Prettier 2.3
const accountCount = (
findItemInSection(
BOOKMARKED_PROJECTS_SECTION_NAME,
"My bookmarks"
) as TreeItem
).getChildren().length;

Prendre en charge le mot-clé intrinsic (#10390 par @sosukesuzuki)

// Input
type Uppercase<S extends string> = intrinsic;

// Prettier 2.2
Error: unknown type: "TSIntrinsicKeyword"

// Prettier 2.3
type Uppercase<S extends string> = intrinsic;

Prendre en charge TypeScript 4.2 (#10418, #10466, #10546, #10589 par @sosukesuzuki)

Signatures de constructeur abstract
// Input
type T = abstract new () => void;

// Prettier 2.2
SyntaxError: Unexpected token, expected ";" (1:19)

// Prettier 2.3
type T = abstract new () => void;

Importations de type dans les déclarations import require
// Input
import type A = require("A");

// Prettier 2.2
SyntaxError: Only ECMAScript imports may use 'import type'.

// Prettier 2.3
import type A = require("A");

Corriger le positionnement des commentaires dans les unions et intersections (#10457 par @thorn0)

// Input
type Foo = "1" | "2" /* two */ | "3";

// Prettier 2.2
type Foo = "1" | "2" | /* two */ "3";

// Prettier 2.3
type Foo = "1" | "2" /* two */ | "3";

Ne pas imprimer de parenthèses autour des assertions de type imbriquées (#10702 par @thorn0)

// Input
foo as unknown as Bar

// Prettier 2.2
(foo as unknown) as Bar;

// Prettier 2.3
foo as unknown as Bar;

Prendre en charge TypeScript 4.3 via babel-ts (#10811 par @sosukesuzuki)

Modificateurs override dans les éléments de classe
class Foo extends  {
override method() {}
}
Signatures d'index statiques ([key: KeyType]: ValueType) dans les classes
class Foo {
static [key: string]: Bar;
}
get / set dans les déclarations de type
interface Foo {
set foo(value);
get foo(): string;
}

Flow

Correction de l'absence de point-virgule dans declare export * from … (#9767 par @fisker)

// Input
declare export * from "ES6_ExportAllFrom_Source2";

// Prettier 2.2
declare export * from "ES6_ExportAllFrom_Source2"

// Prettier 2.3
declare export * from "ES6_ExportAllFrom_Source2";

Prise en charge de l'annotation de type this dans les fonctions via babel-flow (#10397 par @sosukesuzuki)

L'annotation de type this est prise en charge depuis Babel 7.13.

// Input
var foo: (this: boolean) => void;

// Prettier 2.2
SyntaxError: Unexpected token, expected ")" (1:15)

// Prettier 2.3
var foo: (this: boolean) => void;

Correction des problèmes de formatage de plages (#10505 par @thorn0)

Prettier rencontrait des difficultés à formater certaines plages dans les déclarations de fonction. Une SyntaxError était levée. Prettier 2.3 formate ces cas sans erreur. Des exemples de plages problématiques sont présentés ci-dessous :

declare export function graphql<Props, Variables, Component: React$ComponentType<Props>>
// ^^^^^ range 1
(query: GQLDocument, config?: Config<Props, QueryConfigOptions<Variables>>):
(Component: Component) => React$ComponentType<$Diff<React$ElementConfig<Component>, {
data: Object|void,
// ^^^^ range 2
mutate: Function|void
}>>

Prise en charge du type d'accès indexé de Flow (#10594 par @gkz)

// Input
const x: Obj['foo'] = 1;

// Prettier 2.2
// Error: unsupported node type "IndexedAccessType"

// Prettier 2.3
const x: Obj["foo"] = 1;

Prise en charge du type d'accès indexé de Flow (#10788 par @gkz)

// Input
type T = Obj?.['foo'];

// Prettier 2.2
// Error: unsupported node type "OptionalIndexedAccessType"

// Prettier 2.3
type T = Obj?.['foo'];

JSON

N'utilisez pas les guillemets intelligents pour JSON5 avec --quote-props=preserve (#10323 par @thorn0)

Avec l'option quoteProps définie sur preserve et singleQuotes sur false (par défaut), les guillemets doubles sont toujours utilisés pour imprimer les chaînes, y compris dans des cas comme "bla\"bla". Cela permet d'utiliser --parser json5 pour du "JSON avec commentaires et virgules en fin de ligne".

// Input
{
"char": "\"",
}

// Prettier 2.2
{
"char": '"',
}

// Prettier 2.3
{
"char": "\"",
}

Analyseur JSON plus strict (#10346, #10443, #10456, #10434 par @fisker)

En interne, Prettier utilise un analyseur d'expressions JavaScript pour analyser le JSON. C'est pourquoi les analyseurs json et json5 étaient très permissifs et autorisaient toutes sortes d'expressions JavaScript. Ils sont désormais beaucoup plus stricts, bien qu'une syntaxe non standard simple soit toujours autorisée (par exemple, JSON6 est pris en charge, sauf pour les signes moins multiples : ----123).

// Input
[1, 2, 1 + 2]

// Prettier 2.2
[1, 2, 1 + 2]

// Prettier 2.3
SyntaxError: BinaryExpression is not allowed in JSON. (1:8)
> 1 | [1, 2, 1 + 2]
| ^

Amélioration du message d'erreur (#10433 par @fisker)

// Input
{key: "foo" + "bar"}

// Prettier 2.2 (--parser=json-stringify)
SyntaxError: BinaryExpression is not allowed in JSON. (1:7)
> 1 | {key: "foo" + "bar"}
| ^

// Prettier 2.3
SyntaxError: BinaryExpression is not allowed in JSON. (1:7)
> 1 | {key: "foo" + "bar"}
| ^^^^^^^^^^^^^

Correction d'une erreur de syntaxe lors du formatage de plages JSON (#10497 par @fisker)

// Input
[{ a: 1.0000}, {"b": 2.0000 }]
// ^^^^^^^^^^^ range

// Prettier 2.2
SyntaxError: Unexpected token (1:4)
> 1 | "b": 2.0000
| ^

// Prettier 2.3
[{ a: 1.0000}, { "b": 2.0 }]

CSS

Correction des chemins absolus dans les appels -custom-url() en CSS (#9966 par @vjeux)

L'analyseur CSS interprétait cela comme ["division", "absolute/path"] au lieu d'un seul jeton "/absolute/path", sauf dans un appel url(). Comme nous ajoutions un espace après la division, cela produisait un chemin incorrect. La solution a été d'éviter d'imprimer un espace si une division est le premier jeton d'un appel, ce qui devrait être sûr.

/* Input */
-custom-url(/absolute/path)

/* Prettier 2.2 */
-custom-url(/ absolute/path)

/* Prettier 2.3 */
-custom-url(/absolute/path)

Exclusion des paramètres @keyframes de l'analyse en tant que variable Less (#10773 par @tmazeika)

/* Input */
@keyframes :global(spin) {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

/* Prettier 2.2 */
@keyframes: global(spin){
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
};

/* Prettier 2.3 */
@keyframes :global(spin) {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

SCSS

Correction des commentaires cassés dans les parenthèses (#9710 par @fisker)

// Input
.simplification {
foo: (
calc() // not a comment anymore
);
}

// Prettier 2.2
.simplification {
foo: (calc() // not a comment anymore);
}

// Prettier 2.3
.simplification {
foo: (
calc() // not a comment anymore
);
}

Correction des cartes avec des clés sous forme de listes ou de cartes (#10005 par @fisker)

// Input
$map: (
('my list'): 'hello world',
);

// Prettier 2.2
TypeError: Cannot read property 'length' of undefined

// Prettier 2.3
$map: (
("my list"): "hello world",
);

Ember / Handlebars

Préservation des commentaires tilde (#9082 par @kangax, @fisker)

{{!-- Input --}}
{{~! Comment }}
{{! Comment ~}}
{{~! Comment ~}}

{{!-- Prettier 2.2 --}}
{{! Comment }}
{{! Comment }}
{{! Comment }}

{{!-- Prettier 2.3 --}}
{{~! Comment }}
{{! Comment ~}}
{{~! Comment ~}}

Ajout d'un mode sensible aux espaces blancs (#9885 par @dcyriller)

--html-whitespace-sensitivity strict
{{!-- Input --}}
<span>123 {{mustache}}</span>
<span>
123 {{mustache}}</span>
<span>123 {{mustache}}
</span>
<span>
123 {{mustache}}
</span>

{{!-- Prettier 2.2 --}}
<span>
123 {{mustache}}
</span>
<span>
123 {{mustache}}
</span>
<span>
123 {{mustache}}
</span>
<span>
123 {{mustache}}
</span>

{{!-- Prettier 2.3 --}}
<span>123 {{mustache}}</span>
<span>
123
{{mustache}}</span>
<span>123
{{mustache}}
</span>
<span>
123
{{mustache}}
</span>

Impression des blockParam finaux sur leur propre ligne (#9978 par @dcyriller)

{{!-- Input --}}
<MyComponent @prop={{true}} @prop2={{true}} @prop3={{true}} @prop4={{true}} as |thing|></MyComponent>
{{#block param hashKey=hashValue hashKey=hashValue hashKey=hashValue as |blockParam|}}
Hello
{{/block}}

{{!-- Prettier 2.2 --}}
<MyComponent
@prop={{true}}
@prop2={{true}}
@prop3={{true}}
@prop4={{true}} as |thing|
/>
{{#block
param
hashKey=hashValue
hashKey=hashValue
hashKey=hashValue as |blockParam|
}}
Hello
{{/block}}

{{!-- Prettier 2.3 --}}
<MyComponent
@prop={{true}}
@prop2={{true}}
@prop3={{true}}
@prop4={{true}}
as |thing|
/>
{{#block
param
hashKey=hashValue
hashKey=hashValue
hashKey=hashValue
as |blockParam|
}}
Hello
{{/block}}

Correction du formatage des attributs (#10145 par @thorn0)

  • correction de l'échappement de {{ dans les attributs et le texte

  • correction du choix entre ' et " pour les attributs avec interpolations

  • correction du bogue avec [object Object] imprimé dans l'attribut class

  • implémentation d'un formatage simple pour l'attribut class, comme Prettier le formatait en HTML avant la v2.3.0

{{!-- Input --}}
<div class="
foo"></div>
<div bar='"{{expr}}"'></div>
<div baz="\{{ non-expression }}"></div>

{{!-- Prettier 2.2 --}}
<div class="[object Object],foo"></div>
<div bar=""{{expr}}""></div>
<div baz="{{ non-expression }}"></div>

{{!-- Prettier 2.3 --}}
<div class="foo"></div>
<div bar='"{{expr}}"'></div>
<div baz="\{{ non-expression }}"></div>

Scinder le contenu texte sur plusieurs lignes (#10179 par @dcyriller)

{{!-- Input --}}
<div>
A long enough string to trigger a line break that would prevent wrapping more and more.
</div>

{{!-- Prettier 2.2 --}}
<div>
A long enough string to trigger a line break that would prevent wrapping more and more.
</div>

{{!-- Prettier 2.3 --}}
<div>
A long enough string to trigger a line break that would prevent wrapping more
and more.
</div>

Préservation des références numériques de caractères (#10550 par @rwjblue et @thorn0)

{{! Input }}
<span class="stampFont" style="font-family: 'stampfont'">&#xf000;</span>

{{! Prettier 2.2 }}
<span class="stampFont" style="font-family: 'stampfont'"></span>

{{! Prettier 2.3 }}
<span class="stampFont" style="font-family: 'stampfont'">&#xf000;</span>

Ne pas casser les moustaches ouvrantes et les chemins (#10586 par @dcyriller)

{{!-- Input --}}
<GlimmerComponent
@errors={{or this.aVeryLongProperty (and this.aProperty (v-get bike "number" "message"))}}
data-test-beneficiary-account-number
/>
<GlimmerComponent
@progress={{aPropertyEngdingAfterEightiethColumnToHighlightAWeirdClosingParenIssue}}
/>

{{!-- Prettier 2.2 --}}
<GlimmerComponent
@errors={{
or
this.aVeryLongProperty
(and this.aProperty (v-get bike "number" "message"))
}}
data-test-beneficiary-account-number
/>
<GlimmerComponent
@progress={{
aPropertyEngdingAfterEightiethColumnToHighlightAWeirdClosingParenIssue
}}
/>

{{!-- Prettier 2.3 --}}
<GlimmerComponent
@errors={{or
this.aLongProperty
(and this.aProperty (v-get bike "number" "message"))
}}
data-test-beneficiary-account-number
/>
<GlimmerComponent
@progress={{aPropertyEngdingAfterEightiethColumnToHighlightAWeirdClosingParenIssue}}
/>

GraphQL

Correction de l'espace manquante après un mot-clé dans les opérations anonymes (#10689 par @patriscus)

# Input
query ($unnamed: String) {
id
}

# Prettier 2.2
query($unnamed: String) {
id
}

# Prettier 2.3
query ($unnamed: String) {
id
}

Markdown

Correction d'un saut de ligne supplémentaire à la fin des blocs de code JavaScript avec littéraux de chaîne (#9736 par @fisker)

<!-- Input -->
Markdown

```js
"· "
```

<!-- Prettier 2.2 -->
Markdown

```js
"· ";

```

<!-- Prettier 2.3 -->
Markdown

```js
"· ";
```

Correction du formatage des front matter vides (#9791 par @fisker)

<!-- Input -->
---
---

# Title

a|b|c|
|:--|:-:|--:|
|d|e|f|

---

text

<!-- Prettier 2.2 -->
---
---
# Title

a|b|c|
|:--|:-:|--:|
|d|e|f|
---

text

<!-- Prettier 2.3 -->
---
---

# Title

| a | b | c |
| :-- | :-: | --: |
| d | e | f |

---

text

Prise en charge du marqueur de fin de document YAML dans le front matter (#9878 par @michaelbeaumont)

Ajout de la possibilité de délimiter la fin du front matter avec ....

<!-- Input -->
---
title: Hello
slug: home
...

Markdown

<!-- Prettier 2.2 -->
---

title: Hello
slug: home
...

Markdown

<!-- Prettier 2.3 -->
---
title: Hello
slug: home
...

Markdown

YAML

Correction d'une SyntaxError lancée incorrectement sur des ancres suivies de lignes vides (#10516 par @eemeli & @thorn0)

Prettier ne parvenait pas à parser ce YAML valide. Merci à Eemeli Aro d'avoir corrigé ce bug dans le parser sous-jacent.

# Input
key1: &default

subkey1: value1

key2:
<<: *default

# Prettier 2.2
SyntaxError: Nested mappings are not allowed in compact mappings (1:7)

# Prettier 2.3
key1: &default
subkey1: value1

key2:
<<: *default

API

Traiter .prettierrc comme du YAML lors de son formatage (#8105 par @fisker)

Le fichier .prettierrc peut être écrit en JSON ou YAML. Auparavant, lorsque Prettier le formatait, le parser était inféré comme json, ce qui provoquait une SyntaxError si le contenu était du YAML. Désormais, il est traité comme un fichier YAML. Toutefois, s'il s'agit de JSON, il sera formaté comme du JSON (et non comme du YAML ressemblant à du JSON).

Utiliser des tableaux au lieu de concat (#9733 par @fisker, @thorn0)

Pour simplifier le code des printers d'AST, la structure de données pour la commande de concaténation a été changée de { type: 'concat', parts: Doc[] } à Doc[]. L'ancien format est déprécié, mais par compatibilité, le printer de docs continue de le supporter, et doc.builders.concat (ainsi que d'autres fonctions de construction) continueront de l'utiliser jusqu'à la prochaine version majeure de Prettier.

Si vous développez un plugin, ce changement ne vous concerne que si votre plugin introspecte ou modifie des docs composés. Si c'est le cas, rendez votre plugin compatible avec les futures versions de Prettier en adaptant le code d'introspection pour supporter le nouveau format. Ce changement pourrait aussi potentiellement casser certaines fonctionnalités si un plugin appelle un autre plugin pour imprimer un langage embarqué puis introspecte le doc retourné. Cela semble toutefois peu probable.

Pour remplacer les appels concat(…) dans vos plugins, vous pouvez utiliser l'auto-fix de cette règle ESLint prettier-doc/no-concat.

// Prettier 2.2
myDoc = group(concat(["foo", line, "bar"]));

// Prettier 2.3
myDoc = group(["foo", line, "bar"]);

Correction de la commande IR lineSuffixBoundary (#10122 par @thorn0)

Un bug dans l'implémentation de la commande lineSuffixBoundary limitait significativement son utilité : l'algorithme de printer ne la considérait pas correctement comme un saut de ligne potentiel. Maintenant que le bug est corrigé, nous encourageons les auteurs de plugins à réévaluer cette commande pour simplifier l'impression des commentaires de fin.

// Input
group([
"let foo = [",
indent([
softline,
[lineSuffixBoundary, "item1,"],
line,
[lineSuffixBoundary, "item2,", lineSuffix(" // comment")],
line,
[lineSuffixBoundary, "item3"],
]),
softline,
"];",
])

// Prettier 2.2
let foo = [item1, item2, // comment
item3];

// Prettier 2.3
let foo = [
item1,
item2, // comment
item3
];

Ajout de la commande IR indentIfBreak (#10221 par @thorn)

indentIfBreak(doc, { groupId }) est une version optimisée de ifBreak(indent(doc), doc, { groupId }).

Simplification du callback print (#10557 par @fisker)

Le troisième argument de la méthode print des imprimantes de plugin (le callback print) a été mis à jour. Son premier argument peut désormais être une chaîne de caractères ou un tableau de chaînes.

Pour imprimer le nœud actuel, appelez print sans arguments :

 function print(path, options, print) {
const parts = [];
path.each((childPath) => {
- parts.push(print(childPath));
+ parts.push(print());
}, "children");
return parts;
}

Pour imprimer une propriété du nœud actuel, utilisez "property" ou ["property"] :

 function print(path, options, print) {
- return path.call(print, "property");
+ return print("property");
}

Pour imprimer une sous-propriété du nœud actuel, utilisez ["property1", "property2"] :

 function print(path, options, print) {
// print `node.child.child`
- return path.call(print, "child", "child");
+ return print(["child", "child"]);
}

Voir aussi un exemple dans la documentation.

CLI

Ajout d'une option CLI pour éviter les erreurs sur motif non correspondant (#10058 par @daronmcintosh)

Le CLI Prettier n'affichera plus d'erreur lorsqu'aucun fichier ne correspond au motif glob passé en entrée.

# Prettier 2.2
$ npx prettier --check "prettier/docs/*.yaml"
Checking formatting...
[error] No files matching the pattern were found: "prettier/docs/*.yaml".
All matched files use Prettier code style!

# Prettier 2.3
$ npx prettier --check --no-error-on-unmatched-pattern "prettier/docs/*.yaml"
Checking formatting...
All matched files use Prettier code style!

Ajout d'un indicateur CLI pour déboguer les problèmes d'attachement de commentaires (#10124 par @thorn0)

Un nouvel indicateur CLI --debug-print-comments et une fonctionnalité correspondante pour le Playground.

--debug-print-doc désormais round-trippable (#10169, #10177 par @thorn0)

L'idée est de rapprocher la sortie de --debug-print-doc du code réel pour générer la documentation (la représentation intermédiaire de Prettier). Idéalement, il devrait être possible de l'utiliser sans modification après copier-coller dans un fichier JS. Cet idéal n'a probablement pas été atteint par cette PR, mais on s'en approche. Cela rendra --debug-print-doc et la partie correspondante du Playground un peu plus utiles.

Afficher un message d'erreur quand --find-config-path ne trouve pas de fichier de configuration (#10208 par @fisker)

# Prettier 2.2
$ prettier --find-config-path /prettier.js
# Silently failed

# Prettier 2.3
$ prettier --find-config-path /prettier.js
[error] Can not find configure file for "/prettier.js"

Nettoyer l'affichage des noms de fichiers longs lors du formatage (#10217 par @fisker)

# Prettier 2.2
$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check
Checking formatting...
tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes
tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes
tests\flow-repo\config_module_system_node_resolve_dirname\subdir\custom_resolve_
All matched files use Prettier code style!

# Prettier 2.3
$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check
Checking formatting...
All matched files use Prettier code style!

Ne plus ignorer les chemins contenant des mots spéciaux comme constructor (#10256 par @ashlkv)

Les répertoires dont le nom coïncidait avec les propriétés de Object.prototype étaient ignorés par le CLI Prettier à cause d'un bogue classique (introduit dans Prettier 2.0.0) où les propriétés d'objet n'étaient pas vérifiées comme étant propres.

# Prettier 2.2
$ prettier "js/constructor/*.js" --write
[error] No matching files. Patterns: js/constructor/*.js

# Prettier 2.3
$ prettier "js/constructor/*.js" --write
js/constructor/test.js 42ms