Prettier 3.1 : Nouveau formatage expérimental pour les ternaires et syntaxe de flux de contrôle Angular !
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 réintroduit l'indentation pour les ternaires imbriqués et ajoute un nouveau flag --experimental-ternaries pour essayer un format plus novateur, le "curious ternary", qui s'adapte mieux aux conditionnels profondément imbriqués. Nous sommes impatients de recevoir vos retours sur ce format expérimental avant qu'il ne devienne le comportement par défaut plus tard cette année !
Nous avons également ajouté la prise en charge de la syntaxe de flux de contrôle d'Angular v17. Pour plus de détails sur cette syntaxe, veuillez consulter le billet officiel de sortie d'Angular.
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, comme typescript-eslint, remark et Babel. Merci pour votre soutien continu !
Principales fonctionnalités
JavaScript
Réintroduction de l'indentation pour les ternaires imbriqués (#9559 par @rattrayalex)
// Input
const message =
i % 3 === 0 && i % 5 === 0
? "fizzbuzz"
: i % 3 === 0
? "fizz"
: i % 5 === 0
? "buzz"
: String(i);
// Prettier 3.0
const message =
i % 3 === 0 && i % 5 === 0
? "fizzbuzz"
: i % 3 === 0
? "fizz"
: i % 5 === 0
? "buzz"
: String(i);
// Prettier 3.1
const message =
i % 3 === 0 && i % 5 === 0
? "fizzbuzz"
: i % 3 === 0
? "fizz"
: i % 5 === 0
? "buzz"
: String(i);
Nouveau formatage expérimental pour les ternaires : Une curieuse affaire de ternaires (#13183 par @rattrayalex)
Ceci est implémenté derrière un flag --experimental-ternaries.
Nous déplaçons le ? dans les ternaires multi-lignes à la fin de la première ligne plutôt qu'au début de la seconde, avec plusieurs changements connexes.
Bien que cela puisse paraître étrange au premier abord, les tests bêta montrent qu'après quelques heures d'utilisation, les développeurs trouvent que cela rend les ternaires imbriqués beaucoup plus lisibles et pratiques.
Cette PR résout l'un de nos problèmes les plus votés sans réintroduire les inconvénients de sa solution proposée.
Pour plus de détails, consultez Une curieuse affaire de ternaires.
Exemple
// "Questioning" ternaries for simple ternaries:
const content =
children && !isEmptyChildren(children) ?
render(children)
: renderDefaultChildren();
// "Case-style" ternaries for chained ternaries:
const message =
i % 3 === 0 && i % 5 === 0 ? "fizzbuzz"
: i % 3 === 0 ? "fizz"
: i % 5 === 0 ? "buzz"
: String(i);
// Smoothly transitions between "case-style" and "questioning" when things get complicated:
const reactRouterResult =
children && !isEmptyChildren(children) ? children
: props.match ?
component ? React.createElement(component, props)
: render ? render(props)
: null
: null
Prise en charge des nouvelles syntaxes supportées par Babel 7.23.0 (#15485, #15486, #15487, #15488 par @sosukesuzuki)
Nous prenons en charge les nouvelles syntaxes JS supportées par Babel 7.23.0 !
Importations en phase source
Pour plus de détails, consultez https://github.com/tc39/proposal-source-phase-imports.
import source x from "mod";
Évaluation différée des importations
Pour plus de détails, consultez https://github.com/tc39/proposal-defer-import-eval.
import defer * as ns from "mod";
Assignations avec chaînage optionnel
Pour plus de détails, consultez https://github.com/tc39/proposal-optional-chaining-assignment.
maybeObj?.prop1 = value;
Angular
Prise en charge du flux de contrôle d'Angular (#15606 par @DingWeizhe, @fisker)
Ajout de la prise en charge du flux de contrôle intégré dans Angular 17. Merci de nous faire part de vos retours si vous rencontrez des bogues.
Pour plus de détails sur le flux de contrôle, consultez cet article sur le blog officiel.
https://blog.angular.io/introducing-angular-v17-4d7033312e4b
Autres changements
JavaScript
Correction des commentaires entre les parenthèses et le corps de la fonction (#15326 par @fisker)
// Input
function function_declaration()
// this is a function
{
return 42
}
(function function_expression()
// this is a function
{
return 42
})();
// Prettier 3.0
function function_declaration() {
// this is a function
return 42;
}
(function function_expression() // this is a function
{
return 42;
})();
// Prettier 3.1
function function_declaration() {
// this is a function
return 42;
}
(function function_expression() {
// this is a function
return 42;
})();
// Input
function function_declaration()
// this is a function
{
return 42
}
export default function()
// this is a function
{
return 42
}
// Prettier 3.0
TypeError: Cannot read properties of null (reading 'range')
// Prettier 3.1
function function_declaration() {
// this is a function
return 42;
}
export default function () {
// this is a function
return 42;
}
Levée d'ambiguïté pour les expressions unaires du côté gauche de instanceof et in (#15468 par @lucacasonato)
Des parenthèses sont désormais ajoutées autour de l'expression unaire située du côté gauche des expressions instanceof et in, pour lever l'ambiguïté entre l'opérateur unaire appliqué uniquement à l'opérande de gauche et celui qui s'appliquerait à l'ensemble de l'expression binaire.
Cela permet d'éviter une erreur courante où un utilisateur souhaite écrire !("x" in y) mais écrit par erreur !"x" in y, qui est en réalité interprété comme (!"x") in y, ce qui n'a pas de sens.
// Input
!"x" in y;
!("x" in y);
// Prettier 3.0
!"x" in y;
!("x" in y);
// Prettier 3.1
(!"x") in y;
!("x" in y);
Correction de la casse des sélecteurs dans l'interpolation des composants stylisés (#15472 par @lucasols)
// Input
const StyledComponent = styled.div`
margin-right: -4px;
${Container}.isExpanded & {
transform: rotate(-180deg);
}
`;
const StyledComponent2 = styled.div`
margin-right: -4px;
${abc}.camelCase + ${def}.camelCase & {
transform: rotate(-180deg);
}
`;
// Prettier 3.0
const StyledComponent = styled.div`
margin-right: -4px;
${Container}.isexpanded & {
transform: rotate(-180deg);
}
`;
const StyledComponent2 = styled.div`
margin-right: -4px;
${abc}.camelcase + ${def}.camelCase & {
transform: rotate(-180deg);
}
`;
// Prettier 3.1 -- same as input
Formatage cohérent des chaînes contenant des séquences d'échappement (#15525 par @sosukesuzuki)
// Input
export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =
goog.getMsg("That's all we know");
export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 =
goog.getMsg("That\'s all we know");
// Prettier 3.0
export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =
goog.getMsg("That's all we know");
export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 = goog.getMsg(
"That's all we know",
);
// Prettier 3.1
export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =
goog.getMsg("That's all we know");
export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 =
goog.getMsg("That's all we know");
Amélioration du formatage des assignations dont le côté gauche peut être cassé (#15547 par @sosukesuzuki)
// Input
params["redirectTo"] =
`${window.location.pathname}${window.location.search}${window.location.hash}`;
// Prettier 3.0
params[
"redirectTo"
] = `${window.location.pathname}${window.location.search}${window.location.hash}`;
// Prettier 3.1
params["redirectTo"] =
`${window.location.pathname}${window.location.search}${window.location.hash}`;
TypeScript
Correction du commentaire instable après la dernière propriété de paramètre (#15324 par @fisker)
// Input
class Class {
constructor(
private readonly paramProp: Type,
// comment
) {
}
}
// Prettier 3.0
class Class {
constructor(private readonly paramProp: Type) // comment
{}
}
// Prettier 3.0 (Second format)
class Class {
constructor(
private readonly paramProp: Type, // comment
) {}
}
// Prettier 3.1
class Class {
constructor(
private readonly paramProp: Type,
// comment
) {}
}
Prise en charge du formatage intégré dans les littéraux de gabarits annotés avec as const (#15408 par @sosukesuzuki)
// Input
const GQL_QUERY_WITH_CONST = /* GraphQL */ `
query S { shop }
` as const;
// Prettier 3.0
const GQL_QUERY_WITH_CONST = /* GraphQL */ `
query S { shop }
` as const;
// Prettier 3.1
const GQL_QUERY_WITH_CONST = /* GraphQL */ `
query S {
shop
}
` as const;
Correction de l'impression des commentaires pour le dernier opérande des types union (#15409 par @sosukesuzuki)
// Input
type Foo1 = (
| "thing1" // Comment1
| "thing2" // Comment2
)[]; // Final comment1
type Foo2 = (
| "thing1" // Comment1
| "thing2" // Comment2
) & Bar; // Final comment2
// Prettier 3.0
type Foo1 = (
| "thing1" // Comment1
| "thing2"
)[]; // Comment2 // Final comment1
type Foo2 = (
| "thing1" // Comment1
| "thing2"
) & // Comment2
Bar; // Final comment2
// Prettier 3.1
type Foo1 = (
| "thing1" // Comment1
| "thing2" // Comment2
)[]; // Final comment1
type Foo2 = (
| "thing1" // Comment1
| "thing2" // Comment2
) &
Bar; // Final comment2
Maintien des parenthèses requises autour de certains mots-clés spécifiques comme les identifiants dans les instructions d'expression de type satisfies / as (#15514 par @seiyab)
// Input
(type) satisfies never;
// Prettier 3.0
type satisfies never;
// Prettier 3.1
(type) satisfies never;
Flow
Prise en charge des expressions as et satisfies pour Flow (#15130 par @gkz)
// Input
const x = y as T;
// Prettier 3.0
// <error: unsupported>
// Prettier 3.1
const x = y as T;
Prise en charge des arguments de type sur les éléments d'ouverture JSX pour Flow (#15429 par @SamChou19815)
// Input
<Foo<bar> />;
// Prettier 3.0
<Foo />;
// Prettier 3.1
<Foo<bar> />;
Prise en charge des arguments de type après typeof (#15466 par @sosukesuzuki)
Prend en charge les arguments de type après la syntaxe typeof supportée depuis Flow v0.127.0 :
type Foo = typeof MyGenericClass<string, number>;
SCSS
Ne pas diviser l'appel des fonctions SCSS avec un tiret en tête (#15370 par @auvred)
/* Input */
div {
width: -double(-double(3));
}
/* Prettier 3.0 */
div {
width: -double(- double(3));
}
/* Prettier 3.1 */
div {
width: -double(-double(3));
}
HTML
Correction du formatage des éléments menu et marquee (#15334 par @fisker)
<!-- Input -->
<menu><li><button onclick="copy()">Copy</button></li>
<li><button onclick="cut()">Cut</button></li>
<li><button onclick="paste()">Paste</button></li></menu>
<marquee
direction="down"
width="250"
height="200"
behavior="alternate"
style="border:solid"><marquee behavior="alternate"> This text will bounce </marquee></marquee>
<!-- Prettier 3.0 -->
<menu
><li><button onclick="copy()">Copy</button></li>
<li><button onclick="cut()">Cut</button></li>
<li><button onclick="paste()">Paste</button></li></menu
>
<marquee
direction="down"
width="250"
height="200"
behavior="alternate"
style="border: solid"
><marquee behavior="alternate"> This text will bounce </marquee></marquee
>
<!-- Prettier 3.1 -->
<menu>
<li><button onclick="copy()">Copy</button></li>
<li><button onclick="cut()">Cut</button></li>
<li><button onclick="paste()">Paste</button></li>
</menu>
<marquee
direction="down"
width="250"
height="200"
behavior="alternate"
style="border: solid"
>
<marquee behavior="alternate">This text will bounce</marquee>
</marquee>
Markdown
Encodage des caractères < et > dans les URLs Markdown (#15400 par @vivekjoshi556)
<!-- Input -->
[link](https://www.google.fr/()foo->bar)
<!-- Prettier 3.0 -->
[link](<https://www.google.fr/()foo->bar>)
<!-- Prettier 3.1 -->
[link](<https://www.google.fr/()foo-%3Ebar>)
<!-- Input -->
foo->bar>)
<!-- Prettier 3.0 -->
foo->bar>)
<!-- Prettier 3.1 -->
foo-%3Ebar>)
Ne pas diviser les lignes entre les kana japonais et la marque de son (semi-)voisé COMBINING KATAKANA-HIRAGANA (#15411 par @tats-u)
Cette pull request corrige #15410.
Les caractères kana japonais (semi-)voisés peuvent être divisés en deux points de code. Par exemple, le caractère hiragana /ka/ peut être représenté comme suit :
が (U+304C) → か (U+304B) + ゙ (U+3099) → が (U+304C U+3099)
La plupart des utilisateurs ne rencontrent pas ces expressions sauf dans les chemins de fichiers sous macOS. Cependant, certains caractères ne peuvent être représentés que de cette manière. Certains textes japonais devant distinguer /ŋa̠/ (peu utilisé aujourd'hui) du /ga/ courant utilisent l'expression "か゚" (U+304B U+309A).
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚
Le Markdown ci-dessus était formaté ainsi dans Prettier 3.0 :
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け
゚こ゚
La marque de son semi-voisé passait à la ligne suivante, ce qui est incorrect. Grâce à cette pull request, le Markdown source est désormais formaté comme suit :
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚
け゚こ゚
La marque de son semi-voisé reste désormais attachée au hiragana "け".
API
Acceptation des URL dans prettier.{resolveConfig,resolveConfigFile,getFileInfo}() (#15332, #15354, #15360, #15364 par @fisker)
prettier.resolveConfig(), prettier.resolveConfigFile() et prettier.getFileInfo() acceptent désormais une URL avec le protocole file: ou une chaîne d'URL commençant par file://.
// `URL`
await prettier.resolveConfig(new URL("./path/to/file", import.meta.url));
await prettier.resolveConfigFile(new URL("./path/to/file", import.meta.url));
await prettier.getFileInfo(new URL("./path/to/file", import.meta.url));
await prettier.getFileInfo("/path/to/file", {
ignorePath: new URL("./.eslintignore", import.meta.url),
});
// URL string
await prettier.resolveConfig("file:///path/to/file");
await prettier.resolveConfigFile("file:///path/to/file");
await prettier.getFileInfo("file:///path/to/file");
await prettier.getFileInfo("/path/to/file", {
ignorePath: "file:///path/to/.eslintignore",
});
CLI
Traiter les fichiers pris en charge uniquement par des plugins (#15433 par @sosukesuzuki)
Dans Prettier 3.0, lorsqu'on spécifiait un répertoire depuis la CLI, seuls les fichiers avec des extensions prises en charge par défaut étaient traités.
Dans le scénario suivant, non seulement foo.js mais aussi foo.astro devraient être formatés :
# Prettier 3.0 version
$ ls .
foo.js foo.astro
$ cat .prettierrc
{ "plugins": ["prettier-plugin-astro"] }
$ prettier --write .
foo.js 20ms
Avec cette mise à jour, foo.js et foo.astro seront désormais formatés :
# Prettier 3.1 branch
$ prettier --write .
foo.js 20ms
foo.astro 32ms
Vous pouvez remplacer prettier "**/*" --ignore-unknown par prettier . car ils sont désormais équivalents.
Afficher le mot-clé (unchanged) pour l'accessibilité en CLI avec --write (#15467 par @ADTC)
Auparavant, la seule distinction entre un fichier modifié et un fichier inchangé était la couleur grise du nom de fichier. Dans l'exemple ci-dessous, on ne peut pas distinguer a.js de b.js car la couleur est absente. Ce problème est résolu en ajoutant le mot-clé (unchanged) qui rend la distinction accessible sans couleur.
prettier --write .
# Prettier 3.0
a.js 0ms
b.js 0ms
c.js 0ms (cached)
# Prettier 3.1
a.js 0ms
b.js 0ms (unchanged)
c.js 0ms (unchanged) (cached)
Corriger l'erreur lors du formatage de noms de fichiers contenant des caractères spéciaux (#15597 par @fisker)
prettier "[with-square-brackets].js" --list
# Prettier 3.0
[error] Explicitly specified file was ignored due to negative glob patterns: "[with-square-brackets].js".
# Prettier 3.1
[with-square-brackets].js
