Prettier 3.1: ¡Nuevo formato experimental para ternarios y sintaxis de control de flujo de Angular!
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Esta versión reintroduce la indentación en ternarios anidados junto con una nueva bandera --experimental-ternaries para probar un formato más novedoso de "ternario curioso" que escala mejor en condicionales profundamente anidados. ¡Estamos ansiosos por recibir sus comentarios sobre el formato experimental antes de que se convierta en el comportamiento predeterminado más adelante este año!
También hemos añadido soporte para la sintaxis de control de flujo en Angular v17. Para detalles sobre la sintaxis, lea el anuncio oficial de Angular.
Si aprecias Prettier y deseas apoyar nuestro trabajo, considera patrocinarnos directamente a través de nuestro OpenCollective o patrocinando los proyectos de los que dependemos, como typescript-eslint, remark y Babel. ¡Gracias por tu continuo apoyo!
Destacados
JavaScript
Reintroducción de indentación en ternarios anidados (#9559 por @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);
Nuevo Formato Experimental para Ternarios: El Curioso Caso de los Ternarios (#13183 por @rattrayalex)
Esta funcionalidad se implementa tras la bandera --experimental-ternaries.
Movemos el ? en ternarios multilínea al final de la primera línea en lugar del inicio de la segunda, junto con otros cambios relacionados.
Aunque inicialmente pueda parecer extraño, pruebas beta muestran que tras algunas horas de uso, los desarrolladores encuentran que hace los ternarios anidados mucho más legibles y útiles.
Este PR resuelve uno de nuestros issues más votados sin reintroducir los problemas de soluciones propuestas anteriormente.
Consulte El curioso caso de los ternarios para más detalles.
Ejemplo
// "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
Soporte para nuevas sintaxis admitidas por Babel 7.23.0 (#15485, #15486, #15487, #15488 por @sosukesuzuki)
¡Soportamos nueva sintaxis de JS admitida por Babel 7.23.0!
Importaciones en Fase de Origen (Source Phase Imports)
Consulte https://github.com/tc39/proposal-source-phase-imports para más detalles.
import source x from "mod";
Evaluación Diferida de Importaciones (Deferred Import Evaluation)
Consulte https://github.com/tc39/proposal-defer-import-eval para más detalles.
import defer * as ns from "mod";
Asignaciones con Encadenamiento Opcional (Optional Chaining Assignments)
Consulte https://github.com/tc39/proposal-optional-chaining-assignment para más detalles.
maybeObj?.prop1 = value;
Angular
Soporte para el control de flujo en Angular (#15606 por @DingWeizhe, @fisker)
Se ha añadido soporte para el control de flujo incorporado en Angular 17. Por favor, envíenos sus comentarios si encuentra algún error.
Para más detalles sobre el control de flujo, consulte este artículo en el blog oficial.
https://blog.angular.io/introducing-angular-v17-4d7033312e4b
Otros cambios
JavaScript
Corregir comentario entre paréntesis y cuerpo de función (#15326 por @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;
}
Desambiguar expresiones unarias en el lado izquierdo de instanceof e in (#15468 por @lucacasonato)
Ahora se añaden paréntesis alrededor de expresiones unarias en el lado izquierdo de expresiones instanceof e in, para desambiguar la expresión unaria del lado izquierdo con una unaria que se aplica a toda la expresión binaria.
Esto ayuda a capturar un error común donde un usuario pretende escribir !("x" in y) pero en su lugar escribe !"x" in y, que realmente se analiza como el sin sentido (!"x") in y.
// 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);
Corregir mayúsculas/minúsculas de selectores en interpolaciones de componentes estilizados (#15472 por @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
Formatear consistentemente cadenas que contienen escapes (#15525 por @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");
Mejorar el formato para asignaciones cuyo lado izquierdo puede romperse (#15547 por @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
Corregir comentario inestable después del último parámetro de propiedad (#15324 por @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
) {}
}
Soporte para formato incrustado en literales de plantilla anotados con as const (#15408 por @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;
Corregir impresión de comentario para el último operando de tipos unión (#15409 por @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
Mantener paréntesis requeridos alrededor de identificadores específicos como palabras clave en declaraciones de expresión con satisfies / as expression (#15514 por @seiyab)
// Input
(type) satisfies never;
// Prettier 3.0
type satisfies never;
// Prettier 3.1
(type) satisfies never;
Flow
Soporte para expresiones as y satisfies en Flow (#15130 por @gkz)
// Input
const x = y as T;
// Prettier 3.0
// <error: unsupported>
// Prettier 3.1
const x = y as T;
Soporte para argumentos de tipo en elementos JSX de apertura para Flow (#15429 por @SamChou19815)
// Input
<Foo<bar> />;
// Prettier 3.0
<Foo />;
// Prettier 3.1
<Foo<bar> />;
Soporte para argumentos de tipo después de typeof (#15466 por @sosukesuzuki)
Admite argumentos de tipo después de la sintaxis typeof, compatible desde Flow v0.127.0:
type Foo = typeof MyGenericClass<string, number>;
SCSS
No dividir llamadas a funciones de SCSS con guión inicial (#15370 por @auvred)
/* Input */
div {
width: -double(-double(3));
}
/* Prettier 3.0 */
div {
width: -double(- double(3));
}
/* Prettier 3.1 */
div {
width: -double(-double(3));
}
HTML
Corregir formato de elementos menu y marquee (#15334 por @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
Codificar < y > en URLs de Markdown (#15400 por @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>)
Evitar división de líneas entre kana japonés y la marca COMBINING KATAKANA-HIRAGANA (SEMI-)VOICED SOUND MARK (#15411 por @tats-u)
Esta PR soluciona #15410.
Los caracteres de kana japonés (semi)sonoros pueden dividirse en dos puntos de código. Por ejemplo, el siguiente carácter hiragana /ka/ puede representarse como:
が (U+304C) → か (U+304B) + ゙ (U+3099) → が (U+304C U+3099)
La mayoría de usuarios no utilizan ni encuentran estas expresiones excepto en rutas de archivos en macOS. Sin embargo, existen caracteres que solo pueden representarse así. Algunos textos japoneses que necesitan distinguir /ŋa̠/ (aunque actualmente no pocos japoneses lo usan) del común /ga/ emplean la expresión "か゚" (U+304B U+309A).
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚
El Markdown anterior se formatea en Prettier 3.0 así:
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け
゚こ゚
La marca de sonido semi-sonoro pasa a la siguiente línea, lo cual es incorrecto. Con esta PR, el Markdown fuente ahora se formatea como:
nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚
け゚こ゚
La marca de sonido semi-sonoro ahora permanece unida al hiragana "け".
API
Aceptar URL en prettier.{resolveConfig,resolveConfigFile,getFileInfo}() (#15332, #15354, #15360, #15364 por @fisker)
prettier.resolveConfig(), prettier.resolveConfigFile() y prettier.getFileInfo() ahora aceptan una URL con protocolo file: o cadenas que comiencen con 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
Procesar solo archivos admitidos por plugins (#15433 por @sosukesuzuki)
En Prettier 3.0, al especificar un directorio desde la CLI, solo se procesaban los archivos con extensiones compatibles predeterminadas.
En el siguiente escenario, no solo foo.js sino también foo.astro deberían formatearse:
# Prettier 3.0 version
$ ls .
foo.js foo.astro
$ cat .prettierrc
{ "plugins": ["prettier-plugin-astro"] }
$ prettier --write .
foo.js 20ms
Con esta actualización, ahora se formatearán tanto foo.js como foo.astro:
# Prettier 3.1 branch
$ prettier --write .
foo.js 20ms
foo.astro 32ms
Puedes reemplazar prettier "**/*" --ignore-unknown con prettier . ya que ahora son equivalentes.
Mostrar palabra clave (unchanged) para accesibilidad en CLI con --write (#15467 por @ADTC)
Anteriormente, la única distinción entre un archivo modificado y uno sin cambios era el color gris del nombre del archivo. En el ejemplo siguiente, no podíamos distinguir entre a.js y b.js al faltar el color. Este problema se soluciona añadiendo la palabra clave (unchanged), que hace accesible la distinción sin depender del color.
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)
Corregir error al formatear nombres de archivo que contienen caracteres especiales (#15597 por @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
