Prettier 3.2: Compatibilidad con JSONC y expresiones ICU 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 incluye nuevas características como la adición de un analizador JSONC, soporte para expresiones ICU de Angular y numerosas correcciones de errores.
Seguimos solicitando retroalimentación sobre la opción --experimental-ternaries lanzada en Prettier 3.1. Por favor, lee A curious case of the ternaries y responde mediante el enlace de Google Forms proporcionado.
Además, recomendamos leer Prettier's CLI: A Performance Deep Dive de Fabio Spampinato. Esta CLI más rápida está programada para lanzarse como versión 4.0.
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
JSON
Nuevo analizador jsonc añadido (#15831 por @fisker)
Anteriormente, inferíamos que el analizador de archivos .jsonc era json, pero si queríamos mantener la coma final, debíamos usar una configuración alternativa poco elegante: {parser: "json5", quoteProps: "preserve", singleQuote: false}.
El nuevo analizador jsonc:
-
Siempre entrecomilla las claves de los objetos.
-
Encierra las cadenas con comillas dobles.
-
Por supuesto, respeta la opción
trailingComma.
Angular
Soporte para formateo de expresiones ICU de Angular (#15777 por @sosukesuzuki)
Admite dos tipos de expresiones ICU de Angular: plural y select.
<span i18n>
Updated:
{minutes, plural,
=0 {just now}
=1 {one minute ago}
other {{{minutes}} minutes ago}
}
</span>
<span i18n>
The author is {gender, select, male {male} female {female} other {other}}
</span>
Otros cambios
JavaScript
Evitar introducción de saltos de línea en interpolaciones de plantillas (#15209 por @bakkot)
En una cadena de plantilla como
`this is a long message which contains an interpolation: ${format(data)} <- like this`;
evita añadir saltos de línea al formatear la expresión a menos que ya existan o sean inevitables (por ejemplo, en funciones anidadas). Anteriormente se introducían saltos cuando alguna interpolación era lo suficientemente "no simple":
`this is a long message which contains an interpolation: ${format(
data,
)} <- like this`;
Ahora se mantendrá sin modificar.
Si ya existe un salto de línea dentro de ${...}, se formatea normalmente.
Corregir formato no idempotente en cadenas de métodos con líneas vacías (#15522 por @seiyab)
// Input
Foo.a()
.b();
// Prettier 3.1 (first format)
Foo.a()
.b();
// Prettier 3.1 (second format)
Foo.a().b();
// Prettier 3.2
Foo.a()
.b();
Corregir formato de operadores ternarios en llamadas de función (#15677 por @fisker)
// Input
stopDirectory = await (useCache
? memoizedFindProjectRoot
: findProjectRootWithoutCache)(path.dirname(path.resolve(filePath)));
// Prettier 3.1
stopDirectory = await (useCache
? memoizedFindProjectRoot
: findProjectRootWithoutCache)(path.dirname(path.resolve(filePath)));
// Prettier 3.2
stopDirectory = await (
useCache ? memoizedFindProjectRoot : findProjectRootWithoutCache
)(path.dirname(path.resolve(filePath)));
Soluciona inconsistencias para el encadenamiento opcional (#15806 por @fisker)
Solo ocurre al usar los parsers typescript, meriyah u otros parsers ESTree excepto babel.
// Input
function someFunctionName() {
return isEqual(a.map(([t, _]) => t?.id), b.map(([t, _]) => t?.id));
return isEqual(a?.map(([t, _]) => t?.id), b?.map(([t, _]) => t?.id));
}
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere?.includes(listingId),
);
// Prettier 3.1
function someFunctionName() {
return isEqual(
a.map(([t, _]) => t?.id),
b.map(([t, _]) => t?.id),
);
return isEqual(a?.map(([t, _]) => t?.id), b?.map(([t, _]) => t?.id));
}
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(
([listingId]) => someListToCompareToHere?.includes(listingId),
);
// Prettier 3.2
function someFunctionName() {
return isEqual(
a.map(([t, _]) => t?.id),
b.map(([t, _]) => t?.id),
);
return isEqual(
a?.map(([t, _]) => t?.id),
b?.map(([t, _]) => t?.id),
);
}
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere.includes(listingId),
);
theValue = Object.entries(someLongObjectName).filter(([listingId]) =>
someListToCompareToHere?.includes(listingId),
);
Soluciona problemas con comentarios en if (#15826 por @fisker)
// Input
if (foo) for (i = 2; i > 0; i--) console.log(i); // comment 1
else bar();
for (;;){
if (foo) continue; // comment 2
else bar();
}
// Prettier 3.1
Error: Comment "comment 2" was not printed. Please report this error!
// Prettier 3.2
if (foo)
for (i = 2; i > 0; i--) console.log(i); // comment 1
else bar();
for (;;) {
if (foo)
continue; // comment 2
else bar();
}
TypeScript
Mejora el diseño de alias para tipos condicionales (#15811 por @seiyab)
// Input
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
// Prettier 3.1
type FallbackFlags<F extends Flags | undefined> = Equals<
NonNullableFlag<F>["flags"],
{}
> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
// Prettier 3.2
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
HTML
Soluciona el formato de elementos no cerrados ignorados con prettier-ignore (#15748 por @fisker)
<!-- Input -->
<!-- prettier-ignore -->
<h1>
Hello <span>world!
<!-- Prettier 3.1 -->
<!-- prettier-ignore -->
<h1>
<!-- Prettier 3.2 -->
<!-- prettier-ignore -->
<h1>
Hello <span>world!
Angular
Soluciona bloques de control de Angular ignorados con prettier-ignore (#15827 por @fisker)
<!-- Input -->
<!-- prettier-ignore -->
@if (condition) {
Foo
} @else {
Other
}
<!-- Prettier 3.1 -->
<!-- prettier-ignore -->
@if (condition) {
Foo
}
} @else {
Other
}
<!-- Prettier 3.2 -->
<!-- prettier-ignore -->
@if (condition) {
Foo
}
@else {
Other
}
Evita agregar dos puntos para track en la tercera expresión de bloques for (#15887 por @sosukesuzuki)
<!-- Input -->
@for (item of items; let i = $index; track block) {}
<!-- Prettier 3.1 -->
@for (item of items; let i = $index; track: block) {}
<!-- Prettier 3.2 -->
@for (item of items; let i = $index; track block) {}
Ember / Handlebars
Preserva segmentos literales en rutas (#15605 por @maxpowa)
Soluciona casos donde archivos Handlebars que contenían segmentos literales se reformateaban eliminando estos segmentos, causando errores de sintaxis.
<!-- Input -->
{{input.[funky<api!response]}}
{{input.[this one has spaces]}}
{{input.[anotherone].[0]}}
<!-- Prettier 3.1 -->
{{input.funky<api!response}}
{{input.this one has spaces}}
{{input.anotherone.0}}
<!-- Prettier 3.2 -->
{{input.[funky<api!response]}}
{{input.[this one has spaces]}}
{{input.anotherone.[0]}}
GraphQL
Mejora el formato de tipos union en GraphQL (#15870 por @ArchitGajjar)
# Input
union SearchResult = Conference| Festival | Concert | Venue | Conference| Festival | Concert | Venue
# Prettier 3.1
union SearchResult =
Conference
| Festival
| Concert
| Venue
| Conference
| Festival
| Concert
| Venue
# Prettier 3.2
union SearchResult =
| Conference
| Festival
| Concert
| Venue
| Conference
| Festival
| Concert
| Venue
API
Soporta rutas absolutas como plugins en archivos de configuración (#15666 por @fisker)
// prettier.config.cjs
module.exports = {
plugins: [
// posix style
"/path/to/plugin.js",
// Windows style
"D:\\\\path\\to\\plugin.js",
// Use `require.resolve`
require.resolve("my-awesome-prettier-plugin"),
],
};
Soluciona definiciones de tipos para getFileInfo y getSupportInfo (#15854 por @auvred)
const plugin: Plugin = {};
prettier.getFileInfo("./file.ext", {
plugins: [plugin],
});
prettier.getSupportInfo({ plugins: [plugin], showDeprecated: true });
Varios
Corrige afirmación incorrecta en documentación sobre incompatibilidad de cursorOffset con rangeStart/rangeEnd (#15750 por @ExplodingCabbage)
La opción cursorOffset ha sido compatible con rangeStart/rangeEnd durante más de 5 años gracias al trabajo de @ds300. Sin embargo, la documentación de Prettier (incluyendo el texto CLI --help) seguía afirmando lo contrario erróneamente. La documentación ahora está corregida.
