Prettier 3.7: ¡Mayor consistencia en el formato y nuevas funcionalidades para plugins!
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
¡Nos complace anunciar Prettier 3.7! Esta versión se centra en mejorar la experiencia con TypeScript y Flow, alineando específicamente el formato de clases e interfaces para lograr mayor consistencia y previsibilidad. También queremos conocer tu opinión sobre el próximo cambio para corregir la lógica inconsistente de impresión de llaves de apertura en cuerpos de clase e interfaz.
Además, corregimos numerosos errores, añadimos soporte para nuevas funcionalidades en Angular 21 y GraphQL 16.12, e incorporamos soporte para Front Matter en Handlebars.
Para desarrolladores de plugins, hemos añadido nuevas APIs que brindan mayor control sobre la vinculación de comentarios y el manejo de nodos ignorados.
Si valoras Prettier y quieres apoyar nuestro trabajo, considera patrocinarnos directamente a través de nuestro OpenCollective o apoyando los proyectos de los que dependemos. ¡Gracias por tu continuo respaldo!
Destacados
TypeScript
Corregida la impresión inconsistente entre clase e interfaz (#18094, #18091, #18215 por @fisker)
En esta versión, nos hemos enfocado intensamente en mejorar la consistencia entre el formato de Clase e Interfaz. Anteriormente, estas dos estructuras similares se imprimían de manera bastante diferente, generando inconsistencias visuales. Hemos alineado sus reglas de formato para ofrecer un resultado más predecible y limpio.
Se ha eliminado la sangría adicional para parámetros de tipo en clases
// Input
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
extends A, B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
// Prettier 3.6
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
> extends A,
B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
// Prettier 3.7
interface MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
extends A, B {}
declare class MarkDef<
M extends string | Mark = Mark,
ES extends ExprRef | SignalRef = ExprRef | SignalRef,
>
implements A, B {}
Alinear la impresión de herencias en interfaces con las clases
// Input
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
// Prettier 3.6
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>,
PointOverlayMixins<ES>,
LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
// Prettier 3.7
export interface AreaConfig<ES extends ExprRef | SignalRef>
extends MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
export class AreaConfig<ES extends ExprRef | SignalRef>
implements MarkConfig<ES>, PointOverlayMixins<ES>, LineOverlayMixins<ES> {}
Alinear la impresión de herencia única con superclase
// Input
class ExtendsLongOneWithGenerics
extends
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
class ExtendsLongOneWithGenerics
implements
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
interface ExtendsLongOneWithGenerics
extends
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine,
> {}
// Prettier 3.6
class ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
class ExtendsLongOneWithGenerics
implements
Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
interface ExtendsLongOneWithGenerics
extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
// Prettier 3.7
class ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
class ExtendsLongOneWithGenerics implements Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
interface ExtendsLongOneWithGenerics extends Bar<
SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
ToBreakLineToBreakLineToBreakLine
> {}
Lógica inconsistente de impresión de llave de apertura en cuerpos de clase e interfaz
En Prettier v2.3, para mejorar la separación visual entre la cabecera y el cuerpo de una clase, comenzamos a imprimir la llave de apertura { del cuerpo de clase en una nueva línea cuando la clase tiene múltiples herencias.
// Prettier 2.2
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong {
property: string;
}
// Prettier 2.3
class loooooooooooooooooooong
extends looooooooooooooooooong
implements loooooooooooooooooooong
{
property: string;
}
Sin embargo, no todos están satisfechos con este cambio.
Cuéntanos qué opinas sobre aplicar este cambio a las interfaces dejando un comentario en este issue.
Si tienes una mejor solución para este problema, estaremos encantados de discutirla contigo.
A menos que surja una solución mejor, alinearemos la impresión del cuerpo de la interfaz con la del cuerpo de clase en Prettier v4.
// Input
declare class loooooooooooooooooooong
implements looooooooooooooooooong, loooooooooooooooooooong {
property: string;
}
interface loooooooooooooooooooong
extends looooooooooooooooooong, loooooooooooooooooooong {
property: string;
}
// Prettier 3.7
declare class loooooooooooooooooooong
implements looooooooooooooooooong, loooooooooooooooooooong
{
property: string;
}
interface loooooooooooooooooooong
extends looooooooooooooooooong, loooooooooooooooooooong { // <-- This
property: string;
}
Estos cambios también afectan a la sintaxis de Flow
Otros cambios
JavaScript
Permitir dividir atributos de importación en múltiples líneas (#17329 por @fisker)
// Input
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with {
BABEL_8_BREAKING: "false",
USE_ESM: "true", IS_STANDALONE: "false" };
// Prettier 3.6
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with { BABEL_8_BREAKING: "false", USE_ESM: "true", IS_STANDALONE: "false" };
// Prettier 3.7
import syntaxImportAssertions from "@babel/plugin-syntax-import-assertions" with {
BABEL_8_BREAKING: "false",
USE_ESM: "true",
IS_STANDALONE: "false",
};
Añadir soporte para la propuesta "Discard Bindings" (#17708 por @fisker)
La propuesta en Etapa 2 "Discard Bindings" ahora es compatible a través de Babel. Ten en cuenta también nuestra política sobre sintaxis no estandarizada antes de usar esta característica de sintaxis propuesta con Prettier.
const [void] = x;
const {x:void} = x;
Corregir formato inconsistente en comentarios (#17723 por @fisker)
// Input
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.6 (--parser=typescript --experimental-operator-position=start)
if (
true
&& // This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.6 (--parser=babel --experimental-operator-position=start)
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
// Prettier 3.7
if (
true
// This is a really complicated part of the condition, so we need a big ol'
// comment here to explain it.
&& flibble.blibble.blobble?.bloo
) {
doThings();
}
Agregar funciones adicionales de prueba en Playwright (#17876 por @BPScott)
Prettier ya evitaba cambiar la indentación en funciones de prueba al agregar .skip. Ahora también trata las funciones de Playwright test.fixme, test.describe.skip y test.describe.fixme de manera similar a test.skip.
// Input
test.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe.skip("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
// Prettier 3.6
test.fixme(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
test.describe.skip(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
test.describe.fixme(
"does something really long and complicated so I have to write a very long name for the test",
() => {
// code
},
);
// Prettier 3.7
test.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe
.skip("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
test.describe
.fixme("does something really long and complicated so I have to write a very long name for the test", () => {
// code
});
Evitar saltos de línea en {import,require.resolve,require.resolve.paths,import.meta.resolve}() con nombres de módulo largos (#17882, #17908 por @kovsu & @fisker)
// Input
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b = require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const c = require.resolve.paths("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const d = await import("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module")
const e = import.meta.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
// Prettier 3.6
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b = require.resolve(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
const c = require.resolve.paths(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
const d = await import(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module"
);
const e = import.meta.resolve(
"./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module",
);
// Prettier 3.7
const a = require("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const b =
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const c = require.resolve
.paths("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const d =
await import("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
const e = import.meta
.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
Mejorar el manejo de comentarios dentro de sentencias if (#17998 por @fisker)
// Input
if (foo) // comment
{
doThing();
} else // comment for else
{
doSomethingElse();
}
// Prettier 3.6
if (foo) {
// comment
doThing();
} // comment for else
else {
doSomethingElse();
}
// Prettier 3.7
if (foo) // comment
{
doThing();
} else // comment for else
{
doSomethingElse();
}
Mejorar llamadas require() con comentarios (#18037 por @fisker)
// Input
require(
// Comment
"foo"
);
// Prettier 3.6
require(// Comment
"foo");
// Prettier 3.7
require(
// Comment
"foo",
);
Eliminar indentación en expresiones lógicas dentro de llamadas Boolean() (#18087 por @kovsu)
Reduce las diferencias al cambiar una condición a su valor opuesto, o al alternar entre !! y Boolean().
// Input
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
// Prettier 3.6
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition,
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
// Prettier 3.7
const foo = Boolean(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
const bar = !!(
a_long_long_condition ||
a_long_long_long_condition ||
a_long_long_long_condition
);
Corregir manejo de comentarios en sentencias for (#18099 por @fisker, @sosukesuzuki)
// Input
for (x of y)
// Comment
bar();
// Prettier 3.6
// Comment
for (x of y) bar();
// Prettier 3.7
for (x of y)
// Comment
bar();
Mejorar impresión de comentarios alrededor de sentencias vacías (#18108 por @fisker)
// Input
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index ++
) /* No op */;
// Prettier 3.6
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index++ /* No op */
);
// Prettier 3.7
for (
index = 0;
doSomething(foo[index]) !== bar && doSomething(foo[index]) !== baz;
index++
) /* No op */ ;
Corregir impresión inconsistente de comentarios entre métodos de clase y métodos de objeto (#18147 por @fisker)
// Input
class x {
method() // Class method
{
return 1
}
}
const object = {
method() // Object method
{
return 1
}
}
// Prettier 3.6
class x {
method() { // Class method
return 1;
}
}
const object = {
method() {
// Object method
return 1;
},
};
// Prettier 3.7
class x {
method() {
// class method
return 1;
}
}
const object = {
method() {
// object method
return 1;
},
};
Agregar paréntesis faltantes en operadores bitwise (#18163 por @fs0414)
// Input
1 << (bit % 8);
1 >> (bit - 8);
// Prettier 3.6
1 << bit % 8;
1 >> (bit - 8);
// Prettier 3.7
1 << (bit % 8);
1 >> (bit - 8);
Corregir saltos de línea inconsistentes en literales de array (#18172 por @Dunqing, @fisker)
// Input
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides___(-1, -1), [1]);
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides(-1, -1), [1, 2]);
// Prettier 3.6
assert.deepStrictEqual(linesCollection.getViewLinesIndentGuides___(-1, -1), [
1,
]);
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides(-1, -1),
[1, 2],
);
// Prettier 3.7
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides___(-1, -1),
[1],
);
assert.deepStrictEqual(
linesCollection.getViewLinesIndentGuides(-1, -1),
[1, 2],
);
Corregir impresión inconsistente de expresiones lógicas (#18205 por @fisker)
// Input
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b
);
// Prettier 3.6
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
// Prettier 3.7
fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
new Fn(
a &&
a_long_long_long_long_long_long_long_long_long_long_long_long_long_condition
? a
: b,
);
Corregir impresión inconsistente entre CallExpression y NewExpression (#18206 por @fisker)
// Input
TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection
)?.promptType
)
new TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection
)?.promptType
)
// Prettier 3.6
TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
);
new TelemetryTrustedValue(
instance.capabilities.get(
TerminalCapability?.PromptTypeDetection,
)?.promptType,
);
// Prettier 3.7
TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
);
new TelemetryTrustedValue(
instance.capabilities.get(TerminalCapability?.PromptTypeDetection)
?.promptType,
)
Eliminar paréntesis redundantes alrededor de elementos JSX (#18243 por @fisker)
// Input
new A(
<div>
<div></div>
</div>
)
// Prettier 3.6
new A(
(
<div>
<div></div>
</div>
),
);
// Prettier 3.7
new A(
<div>
<div></div>
</div>,
);
Mejora del formato de expresiones lógicas como llamadas en expresiones 'new' (#18245 por @fisker)
// Input
a = new (
a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition
)();
// Prettier 3.6
a = new (a_long_long_long_long_condition ||
a_long_long_long_long_condition ||
a_long_long_long_long_condition)();
// Prettier 3.7
a = new (
a_long_long_long_long_condition ||
a_long_long_long_long_condition ||
a_long_long_long_long_condition
)();
Eliminación de línea vacía en declaraciones 'for' sin cláusula 'update' (#18300 por @fisker)
// Input
for ( let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;i < len;) {}
// Prettier 3.6
for (
let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;
i < len;
) {}
// Prettier 3.7
for (
let i = 0, j = 0, len = allMatches.length, lenJ = selections.length;
i < len;
) {}
Mejora del formato de la superclase (#18325 por @fisker)
// Input
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule.RuleModule {};
// Prettier 3.6
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule
.RuleModule {}
// Prettier 3.7
class EnsureNoDisposablesAreLeakedInTestSuiteSuite
extends eslint.Rule.RuleModule {}
TypeScript
Corrección de posición incorrecta de comentarios después de flechas (#17421 por @o-m12a, @t-mangoe)
// Input
export const test = (): any => /* first line
second line
*/
null;
// Prettier 3.6
export const test = (): any /* first line
second line
*/ => null;
// Prettier 3.6 (Second format)
SyntaxError: Unexpected token (1:22)
> 1 | export const test = (): any /* first line
| ^
2 | second line
3 | */ => null;
4 |
// Prettier 3.7
export const test = (): any =>
/* first line
second line
*/
null;
Adición de paréntesis faltantes en funciones flecha dentro de expresiones de instanciación (#17724 por @fisker)
// Input
void (<_T extends never>() => {})<never>;
// Prettier 3.6
void <_T extends never>() => {}<never>;
// Prettier 3.7
void (<_T extends never>() => {})<never>;
Corrección de formato en TSMappedType (#17785 por @fisker)
// Input (--parser=babel-ts)
export type A = B extends { C?: { [D in infer E]?: F } } ? G : H
// Prettier 3.6
TypeError: Cannot read properties of undefined (reading 'startsWith')
// Prettier 3.7
export type A = B extends { C?: { [D in infer E]?: F } } ? G : H;
Impresión de coma final en opciones de TSImportType (#17798 por @fisker)
La coma final en atributos de tipo import no estaba permitida antes de TypeScript v5.9; ahora se ha corregido el error.
// Input
type A = import("foo", {
with:{
type:'json',
} // <- Should be a comma here
})
// Prettier 3.6
type A = import("foo", {
with: {
type: "json",
} // <- Should be a comma here
});
// Prettier 3.7
type A = import("foo", {
with: {
type: "json",
}, // <- Should be a comma here
});
Mejora de require() en módulos CommonJS con comentarios (#18035 por @fisker)
// Input
import foo = require(
// Comment
"foo"
);
// Prettier 3.6
import foo = require(// Comment
"foo");
// Prettier 3.7
import foo = require(
// Comment
"foo"
);
Salto de línea después de = en parámetros de tipo (#18043 por @fisker)
// Input
export type OuterType2<
LongerLongerLongerLongerInnerType = LongerLongerLongerLongerLongerLongerLongerLongerOtherType
> = { a: 1 };
// Prettier 3.6
export type OuterType2<
LongerLongerLongerLongerInnerType = LongerLongerLongerLongerLongerLongerLongerLongerOtherType,
> = { a: 1 };
// Prettier 3.7
export type OuterType2<
LongerLongerLongerLongerInnerType =
LongerLongerLongerLongerLongerLongerLongerLongerOtherType,
> = { a: 1 };
Eliminación de línea en blanco inesperada antes de tipos unión (#18109 por @jspereiramoura, @fisker)
// Input
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.6
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.7
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
type A = // comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
Este cambio también afecta a la sintaxis de Flow
Corrección de impresión inconsistente de comentarios entre los parsers de typescript y flow (#18110 por @fisker)
// Input
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
& Fooo1000
& Baz2000
& BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.6 (--parser=typescript)
interface A {
a: // Comment
B;
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.6 (--parser=flow)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: Fooo1000 & // Comment
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
// Prettier 3.7 (Same output for `--parser=typescript` and `--parser=flow`)
interface A {
a: B; // Comment
b: // Comment
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
c: // Comment
Fooo1000 &
Baz2000 &
BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
}
Corrección de punto y coma faltante antes de firmas de llamada (#18118 por @fisker)
// Input
interface A {
foo;
<T>(): T;
}
type B = {
foo;
<T>(): T;
}
// Prettier 3.6 (--no-semi, first format)
interface A {
foo
<T>(): T
}
type B = {
foo
<T>(): T
}
// Prettier 3.6 (--no-semi, second format)
interface A {
foo<T>(): T
}
type B = {
foo<T>(): T
}
// Prettier 3.7
interface A {
foo;
<T>(): T
}
type B = {
foo;
<T>(): T
}
Corrección de impresión inconsistente de as const entre parsers de flow y typescript (#18161 por @fisker)
// Input
1 as /* comment */ const;
// Prettier 3.6 (--parser=typescript)
1 as /* comment */ const;
// Prettier 3.6 (--parser=flow)
1 /* comment */ as const;
// Prettier 3.7 (Same output for `--parser=typescript` and `--parser=flow`)
1 /* comment */ as const;
Corrección de comentarios alrededor de expresiones as/satisfies (#18162 por @fisker)
// Input
1 as /*
comment
*/
const;
// Prettier 3.6 (First format)
1 /*
comment
*/ as const;
// Prettier 3.6 (Second format)
SyntaxError: Unexpected keyword or identifier. (3:4)
1 | 1 /*
2 | comment
> 3 | */ as const;
| ^
4 |
// Prettier 3.7
1 as const /*
comment
*/;
Corregir la alineación incorrecta en tipos unión (#18165 por @fisker)
// Input
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression]
}
// Prettier 3.6
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
// Prettier 3.7
interface I {
elements: // comment
| [string, ExpressionNode, ExpressionNode]
| [string, ExpressionNode, ExpressionNode, ObjectExpression];
}
Eliminar línea vacía adicional en tipos unión (#18197 por @Dunqing)
// Input
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
Fooo1000 | Baz2000 | BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.6
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
// Prettier 3.7
type SuperLongTypeNameLoremIpsumLoremIpsumBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBlaBla =
| Fooo1000
| Baz2000
| BarLoooooooooooooooooooooooooooooooooooooooooooooooooLong;
Flow
Añadir soporte básico para sintaxis "match" (#17681 por @fisker)
// Input
const e = match (a) {
1 => true,
'foo' => false,
2 => {obj: 'literal'},
};
// Prettier 3.6
SyntaxError: Unexpected token `{`, expected the token `;` (1:21)
> 1 | const e = match (a) {
| ^
2 | 1 => true,
3 | 'foo' => false,
4 | 2 => {obj: 'literal'},
// Prettier 3.7
const e = match (a) {
1 => true,
"foo" => false,
2 => { obj: "literal" },
};
Añadir soporte para tipos opacos con límites inferior y superior (#17792 por @SamChou19815)
// Input
opaque type Counter super empty extends Box<T> = Container<T>;
opaque type Counter super Box<T> = Container<T>;
declare opaque type Counter super empty extends Box<T>;
declare opaque type Counter super Box<T>;
// Prettier 3.6
SyntaxError: Unexpected identifier, expected the token `=` (1:21)
// Prettier 3.7
opaque type Counter super empty extends Box<T> = Container<T>;
opaque type Counter super Box<T> = Container<T>;
declare opaque type Counter super empty extends Box<T>;
declare opaque type Counter super Box<T>;
CSS
Manejar selectores de atributo con flags de sensibilidad a mayúsculas e insensibilidad (#17841, #17865 por @kovsu)
/* Input */
[type=a s],
[type=a S],
[type=a I] {
list-style-type: lower-alpha;
}
/* Prettier 3.6 */
[type="a s"],
[type="a S"],
[type="a I"] {
list-style-type: lower-alpha;
}
/* Prettier 3.7 */
[type="a" s],
[type="a" S],
[type="a" I] {
list-style-type: lower-alpha;
}
Corregir fallo al formatear propiedades personalizadas especiales (#17899 por @fisker)
/* Input */
:root {
--l: , #000;
}
/* Prettier 3.6 */
TypeError: Cannot read properties of undefined (reading 'value')
/* Prettier 3.7 */
:root {
--l: , #000;
}
Corregir minúsculas incorrectas en selectores dentro de módulos CSS (#17929 por @kovsu)
/* Input */
:export {
nest: {
myColor: blue;
}
myColor: red;
}
/* Prettier 3.6 */
:export {
nest: {
mycolor: blue;
}
myColor: red;
}
/* Prettier 3.7 */
:export {
nest: {
myColor: blue;
}
myColor: red;
}
Corregir formato de selectores CSS que contienen // (#17938 por @kovsu)
/* Input */
a[href="http://example.com"] {
color: red;
}
/* Prettier 3.6 */
a[href="http://example.com"]
{
color: red;
}
/* Prettier 3.7 */
a[href="http://example.com"] {
color: red;
}
Eliminar espacio inesperado entre tamaño de fuente y altura de línea (#18114 por @kovsu)
/* Input */
a {
font: var(--size)/1;
}
/* Prettier 3.6 */
a {
font: var(--size) / 1;
}
/* Prettier 3.7 */
a {
font: var(--size)/1;
}
Corregir sangría adicional en valores CSS separados por coma tras comentario de bloque (#18228 por @seiyab)
/* Input */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
/* Prettier 3.6 */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
/* Prettier 3.7 */
.foo {
background-image:
linear-gradient(to top, blue, red 100%),
/* texture */
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px),
repeating-linear-gradient(90deg, pink, yellow 20px, green 20px, pink 40px);
}
SCSS
Solucionar problema de espacios en paréntesis de argumentos mixin (#17836 por @kovsu)
// Input
.foo {
@include bar('A (B)');
}
// Prettier 3.6
.foo {
@include bar('A( B)');
}
// Prettier 3.7
.foo {
@include bar('A (B)');
}
Corregir formato de valores separados por espacios (#17903 por @kovsu)
// Input
.foo {
@include transition(min-height ($spacer/2) ease-in-out);
}
// Prettier 3.6
.foo {
@include transition(min-height($spacer/2) ease-in-out);
}
// Prettier 3.7
.foo {
@include transition(min-height ($spacer/2) ease-in-out);
}
Less
Corregir minúsculas incorrectas en nombres de variables (#17820 por @kovsu)
// Input
@fooBackground:line-gradient(#f00);
a {
background: @fooBackground;
}
// Prettier 3.6
@foobackground:line-gradient (#f00);
a {
background: @fooBackground;
}
// Prettier 3.7
@fooBackground: line-gradient(#f00);
a {
background: @fooBackground;
}
Mantener ajustados los accesores a propiedades/variables (#17983 por @kovsu)
// Input
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px) [ @result ];
}
// Prettier 3.6
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px) [ @result];
}
// Prettier 3.7
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
padding: .average(16px, 50px)[@result];
}
HTML
Dar soporte al formato del atributo allow en elementos iframe (#17879 por @kovsu)
<!-- Input -->
<iframe allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
<!-- Prettier 3.6 -->
<iframe allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
<!-- Prettier 3.7 -->
<iframe
allow="
layout-animations 'none';
unoptimized-images 'none';
oversized-images 'none';
sync-script 'none';
sync-xhr 'none';
unsized-media 'none';
"
></iframe>
Formatear manejadores de eventos en línea (#17909 por @kovsu)
<!-- Input -->
<button
type="button"
onclick="console .log( 'Hello, this is my old-fashioned event handler!')"
>Press me</button>
<!-- Prettier 3.6 -->
<button
type="button"
onclick="console .log( 'Hello, this is my old-fashioned event handler!')"
>
Press me
</button>
<!-- Prettier 3.7 -->
<button
type="button"
onclick="console.log('Hello, this is my old-fashioned event handler!')"
>
Press me
</button>
Angular
Compatibilidad con Angular 21 (#17722, #18294 by @fisker)
Angular 20.1 agregó compatibilidad con nuevos operadores de asignación. Angular 21 agregó compatibilidad con expresiones regulares.
<!-- Input -->
<b (click)="
a ??= b">{{ /\d+/g}}</b>
<!-- Prettier 3.6 -->
<b
(click)="
a ??= b"
>{{ /\d+/g}}</b
>
<!-- Prettier 3.7 -->
<b (click)="a ??= b">{{ /\d+/g }}</b>
Corrección de duplicación de comentarios en interpolaciones (#17862 by @fisker)
<!-- Input -->
{{a() // comment}}
<!-- Prettier 3.6 -->
{{ a(// comment) // comment }}
<!-- Prettier 3.7 -->
{{
a() // comment
}}
Corrección del formato de la "aserción de no nulo" (#18047 by @fisker)
<!-- Input -->
{{ foo?.bar!.baz }}
<!-- Prettier 3.6 -->
{{ (foo?.bar)!.baz }}
<!-- Prettier 3.7 -->
{{ foo?.bar!.baz }}
Ember / Handlebars
Se agregó compatibilidad con Front Matter a Handlebars (#17781 by @Codezilluh)
Ahora se puede utilizar Front Matter en Handlebars.
---
title: My page title
keywords:
- word
- other word
---
<h1>{{title}}</h1>
<ul>
{{#each keywords}}
<li>{{this}}</li>
{{/each}}
</ul>
Preservar sintaxis else if para ayudantes personalizados (#17856 by @kovsu)
{{! Input }}
{{#animated-if this.foo}}
foo content
{{else if (this.bar)}}
bar content
{{/animated-if}}
{{! Prettier 3.6 }}
{{#animated-if this.foo}}
foo content
{{else}}{{#if (this.bar)}}
bar content
{{/if}}{{/animated-if}}
{{! Prettier 3.7 }}
{{#animated-if this.foo}}
foo content
{{else if (this.bar)}}
bar content
{{/animated-if}}
Eliminar líneas en blanco adicionales en etiquetas <style> (#18065 by @kovsu, @fisker)
{{! Input }}
<style>
#foo {
color: red;
}
</style>
{{! Prettier 3.6 (--html-whitespace-sensitivity=ignore) }}
<style>
#foo {
color: red;
}
</style>
{{! Prettier 3.7 (--html-whitespace-sensitivity=ignore) }}
<style>
#foo {
color: red;
}
</style>
No forzar saltos de línea en elementos con --html-whitespace-sensitivity=ignore (#18133 by @fisker)
{{! Input }}
<div> </div>
{{! Prettier 3.6 (--html-whitespace-ensitivity=ignore) }}
<div>
</div>
{{! Prettier 3.7 (--html-whitespace-ensitivity=ignore) }}
<div></div>
GraphQL
Compatibilidad con "descripciones ejecutables" (#18214 by @fisker)
# Input
"Description"
query {
node {
id
}
}
# Prettier 3.6
SyntaxError: Syntax Error: Unexpected description, descriptions are supported only on type definitions. (1:1)
> 1 | "Description"
| ^
2 | query {
3 | node {
4 | id
# Prettier 3.7
"Description"
query {
node {
id
}
}
Markdown
Mejora en la medición del tamaño de emojis (#17813 by @seiyab)
Este cambio mejora la alineación de tablas en todos los lenguajes.
<!-- Input -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
<!-- Input -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
<!-- Prettier 3.7 -->
| | |
| :-: | :-: |
| ✔ | ✘ |
| ✘ | ✔ |
| ✔ | ✘ |
Inferir analizador TOML para Front Matter (#17965 by @kovsu)
El Front Matter TOML puede ser procesado por el complemento correspondiente si está disponible. También funciona para archivos HTML y CSS.
Corrección del formato de énfasis fuerte (#18010 by @yin1999)
Esta es una corrección complementaria para #17143, donde el PR original no podía determinar si el contenido a izquierda y derecha eran ambos palabras.
<!-- Input -->
1***2***3
1**_2_**3
<!-- Prettier 3.6 -->
1**_2_**3
1**_2_**3
<!-- Prettier 3.7 -->
1***2***3
1***2***3
MDX
Corrección del análisis de import y export (#17996 by @kovsu & @fisker)
{/* Input */}
- import is a word in lists
- export is a word in lists, too!
{/* Prettier 3.6 */}
- import is a word in list
s
- export is a word in lists, too
!
{/* Prettier 3.7 */}
- import is a word in lists
- export is a word in lists, too!
YAML
Preservar línea vacía entre mapas y comentarios (#17843 by @kovsu)
# Input
only: issues
# Comment
# Prettier 3.6
only: issues
# Comment
# Prettier 3.7
only: issues
# Comment
Conservar el marcador de fin de documento explícito (#18296 by @fisker)
# Input
a: a
---
b: b
...
c: c
...
---
d: d
# Prettier 3.6
a: a
---
b: b
---
c: c
---
d: d
# Prettier 3.7
a: a
---
b: b
...
c: c
...
---
d: d
Usar estilo de clave explícito para claves de mapeo en flow con comentarios finales (#18324 by @kovsu, @fisker)
# Input
{ "foo" # comment
:bar }
# Prettier 3.6
{ "foo": bar } # comment
# Prettier 3.7
{ ? "foo" # comment
: bar }
API
Permitir que plugin.parser.preprocess() devuelva una Promise (#17679 by @fisker)
Alineado con plugin.printer.preprocess(), que permite devolver una Promise.
Seguimos recomendando mover tu trabajo asíncrono a plugin.parser.parse(), que ya permite devolver una Promise. Es posible que eliminemos el soporte para plugin.parser.preprocess() en el futuro.
Permitir que AstPath#call() acceda a propiedades de objetos nulos (#17860 by @fisker)
Anteriormente, para verificar un posible nodo hijo inexistente, teníamos que asegurarnos primero de que el nodo existiera.
const isFoo = path.call(() => path.node?.type === "Foo", "foo", "bar");
// Uncaught TypeError: Cannot read properties of undefined (reading 'bar')
Teníamos que
const isFoo =
path.node.foo?.bar &&
path.call(() => path.node?.type === "Foo", "foo", "bar");
A partir de Prettier 3.7, acceder a una propiedad de objetos nulos ya no lanza errores.
Pasar ancestros a plugin.printer.canAttachComment() (#18055 by @fisker)
Esto evita adjuntar comentarios a un hijo específico de un nodo.
Por ejemplo, en este código JavaScript const object = {property};, el nodo Identifier (property) aparece tanto como Property.key y Property.value en el AST, obviamente solo se puede imprimir una vez. Si el comentario se adjunta al hijo que no se imprime, el comentario se perderá.
Los plugins ahora pueden evitar esto añadiendo un canAttachComment así:
export const canAttachComment = (node, [parent]) =>
!(
parent?.type === "Property" &&
parent.shorthand &&
parent.key === node &&
parent.key !== parent.value
);
export const print = (path, options, print) => {
const { node } = path;
switch (node.type) {
case "Property":
if (node.shorthand) {
return print("value");
}
// ...
}
};
Añadir soporte para plugin.printer.printPrettierIgnored() (#18070 by @fisker)
Para un nodo con comentario prettier-ignore, Prettier imprime directamente el texto del nodo. Sin embargo, esto puede causar problemas, por ejemplo, si el nodo necesita paréntesis o requiere imprimir un punto y coma inicial para evitar problemas de ASI en modo --no-semi.
Desde Prettier 3.7, los plugins pueden añadir una función printPrettierIgnored() al printer para personalizar el proceso de impresión de nodos con prettier-ignore. Esta función utiliza la misma firma que plugin.printer.print().
Permitir que un plugin proporcione un printer estree (#18072 by @fisker)
Anteriormente, si un plugin quería crear un printer estree que generara código diferente al incorporado, necesitaba proporcionar tanto parsers como printers. Prettier 3.7 permite crear plugins que solo proporcionen un printer estree.
CLI
Evitar la creación del directorio node_modules/.cache/ cuando --cache no está habilitada (#18124 by @chiawendt)
Ejecutar prettier . sin --cache ya no crea un directorio vacío node_modules/.cache/.
