Prettier 2.3: Asignaciones consistentes, claves cortas sin saltos y Handlebars oficial
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Esta versión se centra en corregir problemas persistentes en el formateador de JavaScript. Advertencia: reformatear un proyecto con esta nueva versión podría generar diferencias significativas. Si no usas ignoreRevsFile para ocultar estos cambios masivos en git blame, quizás sea el momento de hacerlo.
Un hito destacable es el tan esperado lanzamiento del formateador para Ember / Handlebars. Será el último formateador incluido directamente en la biblioteca principal. En el futuro, para garantizar sostenibilidad, los lenguajes solo se añadirán mediante plugins.
Agradecemos a nuestros colaboradores financieros: Salesforce, Indeed, Frontend Masters, Airbnb, Shogun Labs, Skyscanner, Konstantin Pschera y muchos otros que nos ayudan a seguir adelante. Si disfrutas Prettier y quieres apoyar nuestro trabajo, visita nuestro OpenCollective. Considera también apoyar proyectos de los que depende Prettier, como typescript-eslint, remark y Babel.
La mayoría de los cambios en esta versión son gracias al trabajo arduo de Fisker Cheung, Georgii Dolzhykov y Sosuke Suzuki, junto con muchos otros colaboradores.
Recordatorio: al instalar o actualizar Prettier, se recomienda encarecidamente especificar la versión exacta en package.json: "2.3.0", no "^2.3.0".
Destacados
JavaScript
Formateo más consistente en asignaciones (#10222, #10643, #10672 por @thorn0; #10158 por @sosukesuzuki)
Anteriormente, Prettier tenía problemas para determinar cómo romper líneas en asignaciones. Por ejemplo, las expresiones largas del lado derecho a menudo permanecían sin saltos. Esto ya no ocurre.
// 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);
}
Evitar saltos en propiedades con claves cortas (#10335 por @thorn0)
Los saltos de línea tras nombres cortos de propiedades en objetos literales suelen verse antinaturales. Incluso cuando este salto ahorra 1 o 2 caracteres, rara vez se justifica. Prettier 2.3 evita saltos para nombres más cortos que tabWidth + 3 (por ejemplo, 5 caracteres en configuración predeterminada, o 7 con tabWidth: 4). Esta heurística podría revisarse en futuras versiones.
// 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
Promover soporte para Handlebars de alpha a versión estable (#10290 por @dcyriller & @thorn0)
Esto comenzó en 2017. El soporte para Handlebars ha estado en Prettier durante un tiempo, pero nunca se lanzó oficialmente porque no estaba realmente listo. Su estado pasó de "alfa" a "experimental" a "beta" y luego, si revisas las notas de versiones anteriores, verás que después de "beta" inexplicablemente volvió a ser "alfa" nuevamente...
Bueno, en fin, finalmente está sucediendo: ¡Prettier ahora puede formatear oficialmente plantillas HTML con Handlebars! 🎉
Utiliza Glimmer, el parser de Handlebars de Ember, por lo que debería ser compatible con la especificación HTML gracias al equipo de Ember.
La opción --html-whitespace-sensitivity es compatible y por defecto es strict, lo que significa que Prettier siempre respetará la presencia o ausencia de espacios en blanco alrededor de las etiquetas y considerará inseguro agregar espacios donde no había ninguno y viceversa, ya que esto puede afectar cómo se renderiza el documento en el navegador. El valor css aún no es compatible (por ahora se trata como strict).
La característica se llama "Ember / Handlebars" y no simplemente "Handlebars" porque Glimmer no admite cierta sintaxis y casos de uso de Handlebars. Esto se debe principalmente a que Handlebars, al ser un motor de plantillas (un preprocesador), no se preocupa por la sintaxis subyacente del contenido que procesa, mientras que Glimmer analiza dos sintaxis (HTML y Handlebars) simultáneamente y combina el resultado en un único árbol que Prettier puede imprimir. Esto significa que Prettier no formateará archivos Handlebars que no puedan analizarse en dicho árbol, ya sea porque la sintaxis subyacente no es HTML o porque las directivas y etiquetas se superponen de manera que no pueden representarse en un árbol (ej: {{#if foo}}<div>{{/if}). A pesar de estas restricciones, el formateador sigue siendo lo suficientemente útil para usuarios de Handlebars fuera de Ember. En cuanto a la sintaxis no admitida por Ember, hay buenas posibilidades de ver soporte en futuras versiones de Prettier, ya que Glimmer utiliza un parser Handlebars completo bajo el capó.
Los archivos con extensiones .hbs y .handlebars se reconocen como Handlebars por defecto. Para otras extensiones, se debe especificar la opción --parser con el valor glimmer, por ejemplo mediante línea de comandos o, mejor aún, mediante configuration overrides.
¡Mira el formateador en acción en el playground!
Mejoras de Formateo
JavaScript
Refinar el formateo de funciones flecha encadenadas (#9992, #10543 por @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;
Mejorar el formateo para llamadas de React Hooks (#10238 por @sosukesuzuki)
// Prettier 2.2
const { firstName, lastName } = useMemo(() => parseFullName(fullName), [
fullName,
]);
// Prettier 2.3
const { firstName, lastName } = useMemo(
() => parseFullName(fullName),
[fullName]
);
Mejorar la separación visual entre cabecera y cuerpo en clases con cabeceras multilínea (#10085 por @sosukesuzuki)
// Prettier 2.2
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong {
property: string;
}
// Prettier 2.3
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong
{
property: string;
}
Formateo conciso de arrays con solo números (#10106, #10160 por @thorn0)
Aunque en general Prettier evita este tipo de formateo por no ser amigable con los diffs, en este caso especial consideramos que los beneficios superan los riesgos.
Si al menos un elemento tiene un comentario de una sola línea (// ...) en la misma línea, no se aplica el formateo conciso. Por otro lado, los comentarios de una línea en líneas separadas no tienen este efecto y —al igual que las líneas vacías— pueden usarse para agrupación lógica.
// 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,
];
Mejorar el formateo para expresiones await anidadas en cabeceras de expresiones de miembro y llamadas (#10342 por @thorn0)
Aunque Prettier intenta ser útil aquí, por favor no escribas código así. Ten piedad de tus compañeros y usa variables intermedias.
// 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;
Mejorar el formateo para expresiones do en llamadas de funciones (#10693 por @sosukesuzuki)
Las "expresiones do" son una propuesta de ECMAScript en etapa 1.
// Prettier 2.2
expect(
do {
var bar = "foo";
bar;
}
).toBe("foo");
// Prettier 2.3
expect(do {
var bar = "foo";
bar;
}).toBe("foo");
Indentación consistente para operadores condicionales (#10187, #10266 por @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
Formateo multilínea basado en prefijos para el atributo class (#7865 por @thorn0)
El formateo de nombres de clase en HTML ahora mantendrá las clases en una sola línea hasta alcanzar el límite de longitud. Al superarlo, las clases consecutivas con el mismo prefijo se agruparán en líneas separadas. Para frameworks de diseño como Bootstrap y Tailwind CSS, que agregan múltiples clases a un elemento, esto mejora la legibilidad y mantenibilidad frente al comportamiento anterior (mantener todas las clases en una línea) o alternativas como colocar cada clase en su propia línea.
<!-- 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>
Otros cambios
JavaScript
Corregir inestabilidad con múltiples comentarios en la misma línea (#9672 por @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;
Evitar formatear nodos que finalizan justo antes de rangeStart (#9704 por @fisker)
Anteriormente, durante el formateo por rangos, estos nodos se consideraban parte del rango. Ahora se excluyen. Esto afecta a otros lenguajes que admiten esta función, no solo 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;
Corregir comentarios dentro de etiquetas de cierre JSX (#9711 por @fisker)
// Input
<a><// comment
/a>;
// Prettier 2.2
<a></// comment
a>;
// Prettier 2.3
<a></
// comment
a
>;
Corregir detección inconsistente de comentarios de lenguaje (#9743 por @fisker)
Un comentario /* HTML */ debe preceder directamente a un literal de plantilla para que este se reconozca como HTML-en-JS. Anteriormente, el comentario se detectaba erróneamente en otras ubicaciones.
// 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>`;
Corregir punto y coma adicional agregado a directivas ignoradas (#9850 por @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";
}
Corregir formateo inestable de JSX con U+3000 (#9866 por @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>;
Corregir error en expresiones como a(b => c => function (){}) (#10278 por @thorn0)
Regresión desde 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 () {});
Mejorar formateo para decoradores en línea (#10296 por @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() {}
}
Corregir protección ASI para campos privados (#10334 por @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"]() {}
}
Soporte para la propuesta Module Blocks (#10417 por @sosukesuzuki, @thorn0)
Soporte de formateo para la propuesta Module Blocks en Etapa 2.
// Input
module { export let foo = "foo"; };
// Prettier 2.2
SyntaxError: Unexpected token, expected ";"
// Prettier 2.3
module {
export let foo = "foo";
};
Corregir paréntesis faltantes para yield en un pipeline (#10446 por @fisker)
// Input
function* f() {
return x |> (yield #);
}
// Prettier 2.2
function* f() {
return x |> yield #;
}
// Prettier 2.3
function* f() {
return x |> (yield #);
}
Hacer la recuperación de errores de Babel más selectiva (#10495 por @fisker, #9787 por @sosukesuzuki, #10065, #10322 por @thorn0)
Anteriormente, debido a la recuperación de errores, el parser de Babel era demasiado permisivo, lo que generaba diversas formas de AST que Prettier no podía formatear. Prettier 2.3 permite que Babel se recupere solo de ciertos tipos de errores inofensivos, como múltiples declaraciones const con el mismo nombre. Cualquier otro error se reporta como error de sintaxis.
// 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] | ^ ^
Evitar ajuste del último argumento en arrays solo numéricos (#10517 por @thorn0)
Otro caso especial para arrays que contienen exclusivamente números.
// 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]
),
]);
Mejorar detección de define de AMD (#10528 por @thorn0)
Prettier maneja especialmente las llamadas AMD define para evitar saltos de línea inesperados. Ahora solo formatea llamadas define si están en el nivel superior de una función o programa y reciben argumentos como AMD espera.
// Prettier 2.2
const someVariable = define("some string literal", anotherVariable, yetAnotherVariable);
// Prettier 2.3
const someVariable = define(
"some string literal",
anotherVariable,
yetAnotherVariable
);
Corregir comentarios prettier-ignore duplicados (#10666 por @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;
Procesar grupos condicionales en mapDoc (#10695 por @thorn0)
En particular, esto corrige sustituciones rotas en HTML dentro de 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>`;
}
Evitar expansión de argumentos que genera código incorrecto (#10712 por @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()
);
Corregir paréntesis faltantes alrededor de async en for-of (#10781 por @fisker)
Ver 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 []);
Agregar soporte para propuesta async do expressions (#10813 por @sosukesuzuki)
Ver 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
Corregir comentarios faltantes en MethodDefinition (#9872 por @fisker)
Solo en parser typescript, babel-ts no tiene este problema.
// 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 */();
}
Corregir saltos de línea innecesarios en parámetros de declaración de tipos de métodos (#10024 por @sosukesuzuki, #10357 por @thorn0)
// Input
type Foo = {
method(foo: "foo"): `
`
};
// Prettier 2.2
type Foo = {
method(
foo: "foo"
): `
`;
};
// Prettier 2.3
type Foo = {
method(foo: "foo"): `
`;
};
Imprimir comas finales en parámetros de tipo (#10109 por @sosukesuzuki, #10353 por @thorn0)
TypeScript ha admitido comas finales en parámetros de tipo desde TypeScript 2.7, lanzado en enero de 2018. Prettier 2.3 las imprime si la opción trailingComma está configurada como all. Mantén esta opción en el valor predeterminado más conservador, es5, si se necesita compatibilidad con TypeScript 2.7 o versiones anteriores. Ten en cuenta que TypeScript todavía no admite comas finales en argumentos de tipo (instanciaciones de parámetros de tipo).
// 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,
> {
// ...
}
Permitir ajustar argumentos que son funciones flecha no concisas con anotaciones de tipo de retorno (#10316 por @thorn0)
// Prettier 2.2
users.map(
(user: User): User => {
return user;
}
);
// Prettier 2.3
users.map((user: User): User => {
return user;
})
Corregir paréntesis para aserciones no nulas (#10337 por @thorn0)
A veces no se imprimían los paréntesis necesarios en expresiones que contenían aserciones no nulas. Esto se ha corregido.
// 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]!);
Indentar aserciones de tipo en cabeceras de expresiones de miembros y llamadas (#10341 por @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;
Admitir la palabra clave intrinsic (#10390 por @sosukesuzuki)
// Input
type Uppercase<S extends string> = intrinsic;
// Prettier 2.2
Error: unknown type: "TSIntrinsicKeyword"
// Prettier 2.3
type Uppercase<S extends string> = intrinsic;
Admitir TypeScript 4.2 (#10418, #10466, #10546, #10589 por @sosukesuzuki)
Firmas de construcción abstract
// Input
type T = abstract new () => void;
// Prettier 2.2
SyntaxError: Unexpected token, expected ";" (1:19)
// Prettier 2.3
type T = abstract new () => void;
Importaciones de tipo en declaraciones de importación 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");
Corregir comentarios mal ubicados en uniones e intersecciones (#10457 por @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";
No imprimir paréntesis alrededor de aserciones de tipo anidadas (#10702 por @thorn0)
// Input
foo as unknown as Bar
// Prettier 2.2
(foo as unknown) as Bar;
// Prettier 2.3
foo as unknown as Bar;
Admitir TypeScript 4.3 mediante babel-ts (#10811 por @sosukesuzuki)
Modificadores override en elementos de clase
class Foo extends {
override method() {}
}
Firmas de índice estáticas ([key: KeyType]: ValueType) en clases
class Foo {
static [key: string]: Bar;
}
get / set en declaraciones de tipos
interface Foo {
set foo(value);
get foo(): string;
}
Flow
Corregir punto y coma faltante en declare export * from … (#9767 por @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";
Soporte para anotación de tipo this en funciones mediante babel-flow (#10397 por @sosukesuzuki)
La anotación de tipo this es compatible desde 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;
Corregir problemas de formateo por rangos (#10505 por @thorn0)
Prettier tenía problemas para formatear ciertos rangos en declaraciones de funciones. Se producía un SyntaxError. Prettier 2.3 formatea estos casos sin errores. A continuación se muestran ejemplos de rangos problemáticos:
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
}>>
Soporte para tipo de acceso indexado de Flow (#10594 por @gkz)
// Input
const x: Obj['foo'] = 1;
// Prettier 2.2
// Error: unsupported node type "IndexedAccessType"
// Prettier 2.3
const x: Obj["foo"] = 1;
Soporte para tipo de acceso indexado opcional de Flow (#10788 por @gkz)
// Input
type T = Obj?.['foo'];
// Prettier 2.2
// Error: unsupported node type "OptionalIndexedAccessType"
// Prettier 2.3
type T = Obj?.['foo'];
JSON
No usar comillas inteligentes en JSON5 con --quote-props=preserve (#10323 por @thorn0)
Con la opción quoteProps establecida en preserve y singleQuotes en false (valor predeterminado), siempre se usan comillas dobles para imprimir cadenas, incluso en situaciones como "bla\"bla". Esto permite usar --parser json5 para "JSON con comentarios y comas finales".
// Input
{
"char": "\"",
}
// Prettier 2.2
{
"char": '"',
}
// Prettier 2.3
{
"char": "\"",
}
Analizador de JSON más estricto (#10346, #10443, #10456, #10434 por @fisker)
Prettier internamente usaba un analizador de expresiones JavaScript para procesar JSON. Por eso los analizadores json y json5 solían ser muy permisivos y aceptaban todo tipo de expresiones JavaScript. Ahora son mucho más estrictos, aunque aún se permite cierta sintaxis no estándar simple (por ejemplo, se admite JSON6, excepto múltiples signos de menos: ----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]
| ^
Mejorar mensajes de error (#10433 por @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"}
| ^^^^^^^^^^^^^
Corregir error de sintaxis en formateo por rangos de JSON (#10497 por @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
Corregir ruta absoluta en llamadas CSS personalizadas -custom-url() (#9966 por @vjeux)
El analizador de CSS interpreta esto como ["division", "absolute/path"] en lugar de un único token "/absolute/path", a menos que estés en una llamada url(). Como insertamos un espacio después de la división, esto resultaba en una ruta incorrecta. La solución fue evitar imprimir un espacio si una división es el primer token de una llamada, lo que debería ser seguro.
/* Input */
-custom-url(/absolute/path)
/* Prettier 2.2 */
-custom-url(/ absolute/path)
/* Prettier 2.3 */
-custom-url(/absolute/path)
Excluir parámetros de @keyframes de ser interpretados como variables Less (#10773 por @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
Corregir comentarios rotos dentro de paréntesis (#9710 por @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
);
}
Corregir mapas con claves que son listas u otros mapas (#10005 por @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
Preservar comentarios de tilde (#9082 por @kangax, @fisker)
{{!-- Input --}}
{{~! Comment }}
{{! Comment ~}}
{{~! Comment ~}}
{{!-- Prettier 2.2 --}}
{{! Comment }}
{{! Comment }}
{{! Comment }}
{{!-- Prettier 2.3 --}}
{{~! Comment }}
{{! Comment ~}}
{{~! Comment ~}}
Añadir modo sensible a espacios en blanco (#9885 por @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>
Imprimir blockParam final en su propia línea (#9978 por @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}}
Corregir formato de atributos (#10145 por @thorn0)
-
corregir escape de
{{en atributos y texto -
corregir elección entre
'y"para atributos con interpolaciones -
corregir error de
[object Object]impreso en atributoclass -
implementar formato simple para atributo
class, como lo hacía Prettier en HTML antes de 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>
Dividir contenido de texto en múltiples líneas (#10179 por @dcyriller)
Preservar referencias numéricas de caracteres (#10550 por @rwjblue y @thorn0)
{{! Input }}
<span class="stampFont" style="font-family: 'stampfont'"></span>
{{! Prettier 2.2 }}
<span class="stampFont" style="font-family: 'stampfont'"></span>
{{! Prettier 2.3 }}
<span class="stampFont" style="font-family: 'stampfont'"></span>
Evitar ruptura entre llave de apertura y ruta (#10586 por @dcyriller)
GraphQL
Corregir espacio faltante tras palabra clave en operaciones anónimas (#10689 por @patriscus)
# Input
query ($unnamed: String) {
id
}
# Prettier 2.2
query($unnamed: String) {
id
}
# Prettier 2.3
query ($unnamed: String) {
id
}
Markdown
Corregir nueva línea adicional al final de bloques de código JavaScript con literales de cadena (#9736 por @fisker)
<!-- Input -->
Markdown
```js
"· "
```
<!-- Prettier 2.2 -->
Markdown
```js
"· ";
```
<!-- Prettier 2.3 -->
Markdown
```js
"· ";
```
Corregir formato de front matter vacío (#9791 por @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
Adición de soporte para marcador de fin de documento YAML en front matter (#9878 por @michaelbeaumont)
Se añade la capacidad de delimitar el final del front matter con ....
<!-- Input -->
---
title: Hello
slug: home
...
Markdown
<!-- Prettier 2.2 -->
---
title: Hello
slug: home
...
Markdown
<!-- Prettier 2.3 -->
---
title: Hello
slug: home
...
Markdown
YAML
Corrección de SyntaxError lanzado incorrectamente en anclajes seguidos de líneas vacías (#10516 por @eemeli & @thorn0)
Prettier no podía analizar este YAML válido. Agradecemos a Eemeli Aro por corregir este error en el analizador subyacente.
# 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
Tratar .prettierrc como YAML al formatearlo (#8105 por @fisker)
El archivo .prettierrc puede escribirse en JSON o YAML. Anteriormente, cuando Prettier lo formateaba, se infería que el analizador era json, lo que provocaba un SyntaxError si el contenido era YAML. Ahora se trata como un archivo YAML. Sin embargo, si es JSON, se formateará como JSON (no como YAML similar a JSON).
Usar arreglos en lugar de concat (#9733 por @fisker, @thorn0)
Para simplificar el código de las impresoras AST, la estructura de datos para el comando de concatenación ha cambiado de { type: 'concat', parts: Doc[] } a Doc[]. El formato antiguo está obsoleto, pero por compatibilidad la impresora de documentos aún lo admite, y doc.builders.concat (junto con otras funciones constructoras) seguirá usándolo hasta la próxima versión mayor de Prettier.
Si eres autor de un plugin, este cambio solo te afecta si tu plugin inspecciona o modifica documentos compuestos. Si es tu caso, actualiza tu plugin para versiones futuras de Prettier ajustando el código de inspección para admitir el nuevo formato. Existe una remota posibilidad de que este cambio rompa funcionalidades, específicamente si un plugin llama a otro plugin para imprimir lenguajes embebidos e inspecciona el documento devuelto. Aunque no parece haber motivos para que los plugins hagan esto.
Para reemplazar llamadas concat(…) en tus plugins, puedes usar la corrección automática con esta regla de ESLint: prettier-doc/no-concat.
// Prettier 2.2
myDoc = group(concat(["foo", line, "bar"]));
// Prettier 2.3
myDoc = group(["foo", line, "bar"]);
Corrección del comando IR lineSuffixBoundary (#10122 por @thorn0)
Existía un error en la implementación del comando lineSuffixBoundary que limitaba significativamente su utilidad: el algoritmo de impresión no lo consideraba correctamente como posible salto de línea. Corregido este error, instamos a autores de plugins a probar nuevamente este comando para simplificar la impresión de comentarios finales.
// 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
];
Adición del comando IR indentIfBreak (#10221 por @thorn)
indentIfBreak(doc, { groupId }) es una versión optimizada de ifBreak(indent(doc), doc, { groupId }).
Simplificación de la devolución de llamada print (#10557 por @fisker)
El tercer argumento del método print en los impresores de plugins (el callback print) ha sido actualizado. Ahora su primer argumento puede ser una cadena o un array de cadenas.
Para imprimir el nodo actual, llama a print sin argumentos:
function print(path, options, print) {
const parts = [];
path.each((childPath) => {
- parts.push(print(childPath));
+ parts.push(print());
}, "children");
return parts;
}
Para imprimir una propiedad del nodo actual, usa "property" o ["property"]:
function print(path, options, print) {
- return path.call(print, "property");
+ return print("property");
}
Para imprimir una subpropiedad del nodo actual, usa ["property1", "property2"]:
function print(path, options, print) {
// print `node.child.child`
- return path.call(print, "child", "child");
+ return print(["child", "child"]);
}
Consulte también un ejemplo en la documentación.
CLI
Agregar opción CLI para evitar errores en patrones no coincidentes (#10058 por @daronmcintosh)
La CLI de Prettier ya no mostrará un error cuando ningún archivo coincida con el patrón glob pasado como entrada.
# 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!
Agregar bandera CLI para depurar problemas de adjunción de comentarios (#10124 por @thorn0)
Una nueva bandera CLI --debug-print-comments y funcionalidad correspondiente para el Playground.
--debug-print-doc con ida y vuelta (#10169, #10177 por @thorn0)
El objetivo es acercar la salida de --debug-print-doc al código real para generar documentos (la representación intermedia de Prettier). Idealmente, debería funcionar sin modificaciones después de copiarlo y pegarlo en un archivo JS. Probablemente ese ideal no se haya alcanzado completamente con este PR, pero está muy cerca. Esto hará que --debug-print-doc y la parte correspondiente del Playground sean un poco más útiles.
Imprimir mensaje de error cuando --find-config-path no encuentre archivo de configuración (#10208 por @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"
Limpiar nombres largos de archivos formateados (#10217 por @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!
No omitir rutas de archivo que contengan palabras especiales como constructor (#10256 por @ashlkv)
Los directorios cuyos nombres coincidían con propiedades de Object.prototype eran ignorados por la CLI de Prettier debido a un error clásico (introducido en Prettier 2.0.0) que no verificaba si las propiedades eran propias.
# 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
