Prettier 2.1: ¡nueva opción --embedded-language-formatting y nuevas funciones para JavaScript/TypeScript!
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Esta versión introduce una nueva opción --embedded-language-formatting, añade soporte para nuevas características de JavaScript/TypeScript e incluye numerosas correcciones de errores y mejoras.
Destacados
API
Añade opción --embedded-language-formatting={auto,off} (#7875 por @bakkot, #8825 por @fisker)
Por defecto, cuando Prettier detecta código que sabe formatear dentro de cadenas en otros archivos (como plantillas etiquetadas en JavaScript con una etiqueta llamada html o bloques de código en Markdown), intentará formatear ese código automáticamente.
Este comportamiento puede ser indeseado en ocasiones, ya que podría alterar el funcionamiento de tu código. Esta opción te permite cambiar entre el comportamiento predeterminado (auto) y desactivar completamente esta función (off). Se aplica a todos los lenguajes donde Prettier detecta código incrustado, no solo JavaScript.
// Input
html`
<p>
I am expecting this to come out exactly like it went in.
`;
// using --embedded-language-formatting=auto (or omitting this option)
html`
<p>
I am expecting this to come out exactly like it went in.
</p>
`;
// using --embedded-language-formatting=off
html`
<p>
I am expecting this to come out exactly like it went in.
`;
TypeScript
Soporte para TypeScript 4.0
Elementos de Tupla Etiquetados (#8885 por @fisker, #8982 por @sosukesuzuki)
// Input
type Range = [start: number, end: number];
// Prettier 2.0
SyntaxError: Unexpected token, expected "," (1:20)
> 1 | type Range = [start: number, end: number];
// Prettier 2.1
type Range = [start: number, end: number];
Operadores de Asignación con Cortocircuito (#8982 por @sosukesuzuki)
// Input
a ||= b;
// Prettier 2.0
SyntaxError: Expression expected. (1:5)
> 1 | a ||= b;
// Prettier 2.1
a ||= b;
Anotaciones de tipo en cláusulas catch (#8805 por @fisker)
// Input
try {} catch (e: any) {}
// Prettier 2.0
try {
} catch (e) {}
// Prettier 2.1
try {
} catch (e: any) {}
Otros cambios
JavaScript
Soporte para las propuestas de operadores de tubería F# e Inteligentes (#6319 por @sosukesuzuki, @thorn0, #7979 por @sosukesuzuki)
Tubería estilo F#:
// Input
promises |> await;
// Output (Prettier 2.0)
SyntaxError: Unexpected token (1:18)
> 1 | promises |> await;
| ^
// Output (Prettier 2.1)
promises |> await;
Tubería Inteligente:
// Input
5 |> # * 2
// Output (Prettier 2.0)
SyntaxError: Unexpected character '#' (1:6)
> 1 | 5 |> # * 2
| ^
// Output (Prettier 2.1)
5 |> # * 2
Corrige comentarios al final de línea si van seguidos de espacios en blanco (#8069 por @shisama)
Si una línea de comentario tenía espacios en blanco al final, los comentarios no se detectaban como de fin de línea.
// Input
var a = { /* extra whitespace --> */
b };
var a = { /* no whitespace --> */
b };
// Prettier 2.0
var a = {
/* extra whitespace --> */
b,
};
var a = {
/* no whitespace --> */ b,
};
// Prettier 2.1
var a = {
/* extra whitespace --> */ b,
};
var a = {
/* no whitespace --> */ b,
};
Corregir análisis inconsistente de expresiones inyectadas en literales de plantilla de styled-components (#8097 por @thecodrr)
// Input
const SingleConcat = styled.div`
${something()}
& > ${Child}:not(:first-child) {
margin-left:5px;
}
`
const MultiConcats = styled.div`
${something()}
& > ${Child}${Child2}:not(:first-child) {
margin-left:5px;
}
`
const SeparatedConcats = styled.div`
font-family: "${a}", "${b}";
`
// Prettier 2.0 -- same as input
// Prettier 2.1
const SingleConcat = styled.div`
${something()}
& > ${Child}:not(:first-child) {
margin-left: 5px;
}
`;
const MultiConcats = styled.div`
${something()}
& > ${Child}${Child2}:not(:first-child) {
margin-left: 5px;
}
`;
const SeparatedConcats = styled.div`
font-family: "${a}", "${b}";
`;
Corregir comas finales en objetos cuando la última propiedad se ignora (#8111 por @fisker)
// Input
const foo = {
// prettier-ignore
bar: "baz"
}
// Prettier 2.0
const foo = {
// prettier-ignore
bar: "baz"
};
// Prettier 2.1
const foo = {
// prettier-ignore
bar: "baz",
};
Mantener claves de objetos con secuencias de escape tal cual (#8160 por @fisker)
// Input
const a = {
"\u2139": 'why "\\u2139" converted to "i"?',
};
// Prettier 2.0
const a = {
ℹ: 'why "\\u2139" converted to "i"?',
};
// Prettier 2.1
const a = {
"\u2139": 'why "\\u2139" is converted to "i"?',
};
Corregir espacio extra después del guión en CSS-in-JS (#8255 por @thorn0)
// Input
css`
color: var(--global--color--${props.color});
`
// Prettier 2.0
css`
color: var(--global--color-- ${props.color});
`;
// Prettier 2.1
css`
color: var(--global--color--${props.color});
`;
Corregir comentarios en la parte extends de declaraciones/expresiones de clase (#8312 por @thorn0)
// Input
class a extends a // comment
{
constructor() {}
}
// Prettier 2.0
class a extends a // comment {
constructor() {}
}
// Prettier 2.1
class a extends a { // comment
constructor() {}
}
No envolver arreglos en cadenas de plantilla de test.each de Jest (#8354 por @yogmel)
// Input
test.each`
a | b | c
${1} | ${[{ start: 1, end: 3 },{ start: 15, end: 20 },]} | ${[]}
`("example test", ({a, b, c}) => {})
// Prettier 2.0
test.each`
a | b | c
${1} | ${[
{ start: 1, end: 3 },
{ start: 15, end: 20 }
]} | ${[]}
`("example test", ({ a, b, c }) => {});
// Prettier 2.1
test.each`
a | b | c
${1} | ${[{ start: 1, end: 3 }, { start: 15, end: 20 }]} | ${[]}
`("example test", ({ a, b, c }) => {});
Soporte para insertPragma y requirePragma en archivos con shebang (#8376 por @fisker)
// `--insert-pragma`
// Input
#!/usr/bin/env node
hello
.world();
// Prettier 2.0
SyntaxError: Unexpected token (3:1)
1 | /** @format */
2 |
> 3 | #!/usr/bin/env node
| ^
4 | hello
5 | .world();
// Prettier 2.1
#!/usr/bin/env node
/** @format */
hello.world();
// `--require-pragma`
// Input
#!/usr/bin/env node
/**
* @format
*/
hello
.world();
// Prettier 2.0
#!/usr/bin/env node
/**
* @format
*/
hello
.world();
// Prettier 2.1
#!/usr/bin/env node
/**
* @format
*/
hello.world();
Corregir sangría en formato de rango (#8410 por @thorn0)
> echo -e "export default class Foo{\n/**/\n}" | prettier --range-start 16 --range-end 31 --parser babel
// Prettier 2.0
export default class Foo {
/**/
}
// Prettier 2.1
export default class Foo {
/**/
}
Mejorar detección de elementos fuente para formato de rango (#8419 por @thorn0)
No todos los tipos de declaraciones se detectaban (lee aquí cómo funciona el formato de rango en Prettier).
// Input
for (const element of list) { /* ... */ }
// ^^^^^^^^^^^^^^^^^^^^^^ ← range
// Prettier 2.0
for (const element of list) { /* ... */ }
// Prettier 2.1
for (const element of list) {
/* ... */
}
Soporte para Campos Privados en in (#8431 por @sosukesuzuki)
Soporte para la propuesta en Etapa 2 Campos Privados en in.
// Input
#prop in obj;
// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #prop in obj;
| ^
2 |
// Prettier 2.1
#prop in obj;
Soporte para Atributos de Módulo ES y módulos JSON (#8436 por @fisker)
Soporte para la propuesta en Etapa 2 Atributos de Módulo ES y módulos JSON.
// Input
import foo from "foo.json" with type: "json";
// Prettier 2.0
SyntaxError: Unexpected token, expected ";" (1:28)
> 1 | import foo from "foo.json" with type: "json";
| ^
// Prettier 2.1
import foo from "foo.json" with type: "json";
Soporte para sintaxis de registros y tuplas (#8453 por @fisker)
Soporte para la propuesta en Etapa 2 Propuesta de Registros y Tuplas en JavaScript.
Solo soporta sintaxis #[]/#{}, no {| |} / [| |].
Tuplas
// Input
#[1, 2, 3]
// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #[1, 2, 3]
| ^
// Prettier 2.1
#[1, 2, 3];
Registros
// Input
#{
a: 1,
b: 2,
c: 3,
}
// Prettier 2.0
SyntaxError: Unexpected token (1:1)
> 1 | #{
| ^
2 | a: 1,
3 | b: 2,
4 | c: 3,
// Prettier 2.1
#{
a: 1,
b: 2,
c: 3,
};
Envolver elemento JSX a la izquierda de "<" con paréntesis (#8461 por @sosukesuzuki)
// Input
(<div/>) < 5;
// Prettier 2.0
<div/> < 5;
// Prettier 2.0 second output
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (1:9)
> 1 | <div /> < 5;
| ^
2 |
// Prettier 2.1
(<div />) < 5;
Corregir sangría en expresiones binarias con comentarios finales (#8476 por @sosukesuzuki)
// Input
a +
a + // comment
a;
// Prettier 2.0
a +
a + // comment
a;
// Prettier 2.1
a +
a + // comment
a;
Corrección de comentarios inestables en expresiones binarias (#8491 por @thorn0)
// Input
Math.min(
(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight)
) - devsite_footer_height,
0,
)
// Prettier 2.0 (first output)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);
// Prettier 2.0 (second output)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);
// Prettier 2.1 (first and second outputs)
Math.min(
/* foo */
document.body.scrollHeight -
(window.scrollY + window.innerHeight) -
devsite_footer_height,
0
);
// Input
const topOfDescriptionBox =
Layout.window.width + // Images are 1:1 aspect ratio, full screen width
Layout.headerHeight;
// Prettier 2.0 (first output)
const topOfDescriptionBox =
Layout.window.width + Layout.headerHeight; // Images are 1:1 aspect ratio, full screen width
// Prettier 2.0 (second output)
const topOfDescriptionBox = Layout.window.width + Layout.headerHeight; // Images are 1:1 aspect ratio, full screen width
// Prettier 2.1 (first and second outputs)
const topOfDescriptionBox =
Layout.window.width + // Images are 1:1 aspect ratio, full screen width
Layout.headerHeight;
Comillas en claves numéricas: añadir y eliminar (#8508 por @lydell)
Prettier elimina las comillas de las claves de objeto cuando son identificadores válidos. Ahora también elimina comillas de claves numéricas.
Si usas quoteProps: "consistent", Prettier puede añadir comillas a claves numéricas para que todas las propiedades terminen entrecomilladas.
// Input
x = {
"a": null,
"1": null,
};
// Prettier 2.0
x = {
a: null,
"1": null,
};
// Prettier 2.1
x = {
a: null,
1: null,
};
Prettier solo modifica números "simples" como 1 o 123.5. No hará estas transformaciones por resultar inesperadas:
1e2 -> "100"
0b10 -> "10"
1_000 -> "1000"
1.0 -> "1"
0.99999999999999999 -> "1"
999999999999999999999 -> "1e+21"
2n -> "2"
"1e+100" -> 1e100
(¡Por favor no uses números confusos como claves de objeto!)
Nota: Prettier solo elimina comillas de números usando el parser "babel". No es completamente seguro hacerlo en TypeScript.
Preferir comentarios iniciales cuando hay comentarios después de "?" en tipos condicionales (#8557 por @sosukesuzuki)
// Input
type A = B extends T
? // comment
foo
: bar;
// Prettier 2.0
type A = B extends T // comment
? foo
: bar;
// Prettier 2.1
type A = B extends T
? // comment
foo
: bar;
Romper expresiones ternarias que contengan comentarios multilínea (#8592 por @sosukesuzuki)
// Input
test
? /* comment
comment
*/
foo
: bar;
// Prettier 2.0
test ? /* comment
comment
*/ foo : bar;
// Prettier 2.1
test
? /* comment
comment
*/
foo
: bar;
Corregir pares inestables de comentarios entre métodos de clase (#8731 por @fisker)
// Input
class C {
ma() {} /* D */ /* E */
mb() {}
}
// Prettier 2.0
class C {
ma() {} /* E */ /* D */
mb() {}
}
// Prettier 2.0 (Second format)
class C {
ma() {} /* D */ /* E */
mb() {}
}
// Prettier 2.1
class C {
ma() {} /* D */ /* E */
mb() {}
}
Corregir comentarios prettier-ignore duplicados (#8742 por @fisker)
// Input
a = <div {.../* prettier-ignore */{}}/>
a = <div {...{}/* prettier-ignore */}/>
// Prettier 2.0
a = <div {/* prettier-ignore */ .../* prettier-ignore */ {}} />;
a = <div {...{} /* prettier-ignore */ /* prettier-ignore */} />;
// Prettier 2.1
a = <div {.../* prettier-ignore */ {}} />;
a = <div {...{} /* prettier-ignore */} />;
Soporte para Decimal Proposal (#8901 por @fisker)
Soporte para la propuesta en Etapa 1 Decimal Proposal.
// Input
0.3m;
// Prettier 2.0
SyntaxError: Identifier directly after number (1:4)
> 1 | 0.3m;
// Prettier 2.1
0.3m;
Añadir paréntesis al usar yield con JSX (#9011 por @fisker)
En v2.0.0 eliminamos los paréntesis al usar yield con JSX, lo cual funciona en la mayoría de parsers, pero ESLint genera errores al analizarlo (issue relacionado).
// Input
function* f() {
yield <div>generator</div>
}
// Prettier 2.0
function* f() {
yield <div>generator</div>
}
// Prettier 2.1
function* f() {
yield (<div>generator</div>);
}
TypeScript
Corregir el parser babel-ts para emitir error de sintaxis adecuado en (a:b) (#8046 por @thorn0)
Anteriormente, este código se analizaba sin errores pero fallaba en la impresión, mostrando un mensaje poco claro con traza de pila. Ahora el parser emite un error de sintaxis adecuado.
// Input
(a:b)
// Prettier 2.0
[error] test.ts: Error: unknown type: "TSTypeCastExpression"
[error] ... [a long stack trace here] ...
// Prettier 2.1
[error] test.ts: SyntaxError: Did not expect a type annotation here. (1:2)
[error] > 1 | (a:b)
[error] | ^
[error] 2 |
Añadir paréntesis a literales de cadena para evitar interpretación como directivas (#8422 por @thorn0)
Prettier envuelve cualquier literal de cadena en posición de declaración entre paréntesis porque, de lo contrario, estas cadenas serían interpretadas como directivas si aparecen al principio de una función o programa, lo que podría alterar su comportamiento. Técnicamente no es necesario hacer esto para cadenas que no están en la primera línea de una función o programa. Pero hacerlo de todos modos garantiza mayor coherencia y puede ayudar a detectar errores. Consulta por ejemplo este hilo en Twitter.
Anteriormente, esto no funcionaba consistentemente con el parser de typescript. Solo las cadenas ya envueltas en paréntesis las conservaban.
// Input
f();
'use foo';
('use bar');
// Prettier 2.0
f();
"use foo";
("use bar");
// Prettier 2.1
f();
("use foo");
("use bar");
Compatibilidad con cambio disruptivo de TypeScript 3.9 para Optional Chaining y Non-Null Assertions (#8450 por @sosukesuzuki)
Consulta: https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#breaking-changes
// Input
(a?.b)!.c;
// Prettier 2.0
a?.b!.c;
// Prettier 2.1
(a?.b)!.c;
Flow
Corrige parámetro de tipo de función que contiene parámetro nullable (#8365 por @fisker)
// Input
let f: <A>(
((?A) => B),
) => B;
// Prettier 2.0
let f: <A>((?A) => B) => B;
// Prettier 2.0 (Second format)
SyntaxError: Unexpected token (1:12)
> 1 | let f: <A>((?A) => B) => B;
// Prettier 2.1
let f: <A>(((?A) => B)) => B;
Corrige export default de Flow Enum (#8768 por @gkz)
No añade punto y coma final al exportar por defecto una Flow Enum.
// Input
export default enum B {}
// Prettier 2.0
export default enum B {};
// Prettier 2.1
export default enum B {}
CSS
No romper código con comentario al final de regla at (#7009 por @evilebottnawi)
/* Input */
@at-root .foo
// .bar
{
}
/* Prettier 2.0 */
@at-root .foo
// .bar {
}
/* Prettier 2.1 */
@at-root .foo
// .bar
{
}
Corrige manipulación de contenido sin comillas en url() (#7592 por @mattiacci)
Mejora el manejo de contenido URL sin comillas en CSS/SCSS/Less. Esto no soluciona los problemas subyacentes de parsing, pero al menos asegura que Prettier no modifique las URLs.
/* Input */
@import url(https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&display=swap);
@import url(//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap);
.validUnquotedUrls{
background: url(data/+0ThisShouldNotBeLowerCased);
background: url(https://foo/A*3I8oSY6AKRMAAAAAAAAAAABkARQnAQ);
background: url(https://example.com/some/quite,long,url,with,commas.jpg);
}
/* Prettier 2.0 */
@import url(
https://fonts.googleapis.com/css?family=Roboto:100,
300,
400,
500,
700,
900&display=swap
);
@import url(
//fonts.googleapis.com/css?family=#{get-font-family("Roboto")}:100,
300,
500,
700,
900&display=swap
);
.validUnquotedUrls {
background: url(data/+0thisshouldnotbelowercased);
background: url(https://foo/A*3i8osy6akrmaaaaaaaaaaabkarqnaq);
background: url(https://example.com/some/quite, long, url, with, commas.jpg);
}
/* Prettier 2.1 */
@import url(https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&display=swap);
@import url(//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap);
.validUnquotedUrls{
background: url(data/+0ThisShouldNotBeLowerCased);
background: url(https://foo/A*3I8oSY6AKRMAAAAAAAAAAABkARQnAQ);
background: url(https://example.com/some/quite,long,url,with,commas.jpg);
}
Espacio incorrecto añadido tras dos puntos escapados en nombres de líneas de grid CSS (#8535 por @boyenn)
/* Input */
.grid {
grid-template-rows:
[row-1-00\:00] auto;
}
/* Prettier 2.0 */
.grid {
grid-template-rows: [row-1-00\: 00] auto;
}
/* Prettier 2.1 */
.grid {
grid-template-rows: [row-1-00\:00] auto;
}
Soporte para @supports selector(<custom-selector>) (#8545 por @boyenn)
/* Input */
@supports selector(:focus-visible) {
button:focus {
outline: none;
}
button:focus-visible {
outline: 2px solid orange;
}
}
/* Prettier 2.0 */
@supports selector(: focus-visible) {
button:focus {
outline: none;
}
button:focus-visible {
outline: 2px solid orange;
}
}
/* Prettier 2.1 */
@supports selector(:focus-visible) {
button:focus {
outline: none;
}
button:focus-visible {
outline: 2px solid orange;
}
}
Mejora en manejo de argumentos arbitrarios (#8567, #8566 por @boyenn)
Prettier ya no añade espacio extra inesperado tras funciones al pasar argumentos arbitrarios. Prettier ya no rompe código cuando se usan listas numéricas en línea como argumentos arbitrarios.
/* Input */
body {
test: function($list...);
foo: bar(returns-list($list)...);
background-color: rgba(50 50 50 50...);
}
/* Prettier 2.0 */
body {
test: function($list...);
foo: bar(returns-list($list) ...);
background-color: rgba(50 50 50 50..);
}
/* Prettier 2.1 */
body {
test: function($list...);
foo: bar(returns-list($list)...);
background-color: rgba(50 50 50 50...);
}
SCSS
Corrige indentación extra en líneas posteriores a comentarios en SCSS (#7844 por @boyenn)
Anteriormente, Prettier aplicaba indentación extra en líneas tras comentarios dentro de mapas SCSS. Ahora Prettier ya no aplica estas indentaciones.
/* Input */
$my-map: (
'foo': 1, // Foo
'bar': 2, // Bar
);
/* Prettier 2.0 */
$my-map: (
"foo": 1,
// Foo
"bar": 2,
// Bar
);
/* Prettier 2.1 */
$my-map: (
"foo": 1,
// Foo
"bar": 2,
// Bar
);
Corrige comentarios en línea entre propiedad y valor (#8366 por @fisker)
// Input
a {
color: // comment
red;
}
// Prettier 2.0
a {
color: // comment red;
}
// Prettier 2.1
a {
color: // comment
red;
}
Comentarios al final del archivo se perdían si se omitía el punto y coma final (#8675 por @fisker)
// Input
@mixin foo() {
a {
color: #f99;
}
}
@include foo() /* comment*/
// Prettier 2.0
@mixin foo() {
a {
color: #f99;
}
}
@include foo();
// Prettier 2.1
@mixin foo() {
a {
color: #f99;
}
}
@include foo(); /* comment*/
Less
Corrección de la pseudo-clase :extend (#8178 por @fisker)
Anteriormente el selector se interpretaba como valor; ahora se reconoce correctamente como selector.
// Input
.hello {
&:extend(.input[type="checkbox"]:checked ~ label)}
// Prettier 2.0
.hello {
&:extend(.input[type= "checkbox" ]: checked ~label);
}
// Prettier 2.1
.hello {
&:extend(.input[type="checkbox"]:checked ~ label);
}
Corrección de comentarios en línea que contienen /* (#8360 por @fisker)
Cuando los comentarios en línea contenían /*, algunos otros comentarios no se imprimían correctamente.
// Input
@import "a";
// '/*' <-- this breaks formatting
@import 'b';
/* block */
/*no-space block*/
// Prettier 2.0
@import "a";
// '/*' <-- this breaks formatting
@import "b";
@import 'b
@import 'b';
/* bl
// Prettier 2.1
@import "a";
// '/*' <-- this breaks formatting
@import "b";
/* block */
/*no-space block*/
HTML
Omisión del punto y coma final en atributos de estilo de una sola línea (#8013 por @bschlenk)
<!-- Input -->
<div style="margin: 0; padding: 20px"></div>
<div style="margin: 0; padding: 20px; position: relative; display: inline-block; color: blue"></div>
<!-- Prettier 2.0 -->
<div style="margin: 0; padding: 20px;"></div>
<div
style="
margin: 0;
padding: 20px;
position: relative;
display: inline-block;
color: blue;
"
></div>
<!-- Prettier 2.1 -->
<div style="margin: 0; padding: 20px"></div>
<div
style="
margin: 0;
padding: 20px;
position: relative;
display: inline-block;
color: blue;
"
></div>
Preservación de caracteres de espacio no ASCII en HTML (#8137 por @fisker)
Los caracteres de espacio no ASCII como U+00A0 o U+2005 no se consideran espacios en blanco en HTML y no deben eliminarse.
// Prettier 2.0
[...require("prettier").format("<i> \u2005 </i>", { parser: "html" })]
.slice(3, -5)
.map((c) => c.charCodeAt(0).toString(16));
// -> [ '20' ]
// `U+2005` is removed
// Prettier 2.1
[...require("prettier").format("<i> \u2005 </i>", { parser: "html" })]
.slice(3, -5)
.map((c) => c.charCodeAt(0).toString(16));
// -> [ '20', '2005', '20' ]
Compatibilidad con bloques de script con comentarios HTML heredados (#8173 por @fisker, #8394 por @fisker)
Anteriormente analizábamos los bloques <script> de HTML como "módulo" (gramática de módulos ECMAScript), por lo que no podíamos analizar comentarios que empezaran con <!-- (también conocidos como comentarios de tipo HTML). Ahora analizamos los bloques <script> como "script", excepto cuando este <script>:
-
Tiene
type="module" -
Tiene
type="text/babel"ydata-type="module", introducido en babel@v7.10.0
<!-- Input -->
<SCRIPT>
<!--
alert("hello" + ' world!')
//--></SCRIPT>
<!-- Prettier 2.0 -->
SyntaxError: Unexpected token (2:1)
1 |
> 2 | <!--
| ^
3 | alert("hello" + ' world!')
4 | //-->
<!-- Prettier 2.1 -->
<script>
<!--
alert("hello" + " world!");
//-->
</script>
Tratar <select> como inline-block y <optgroup>/<option> como block (#8275 por @thorn0, #8620 por @fisker)
Ahora Prettier sabe que es seguro añadir espacios en blanco dentro de las etiquetas select, option y optgroup.
<!-- Input -->
<select><option>Blue</option><option>Green</option><optgroup label="Darker"><option>Dark Blue</option><option>Dark Green</option></optgroup></select>
<!-- Prettier 2.0 -->
<select
><option>Blue</option
><option>Green</option
><optgroup label="Darker"
><option>Dark Blue</option><option>Dark Green</option></optgroup
></select
>
<!-- Prettier 2.1 -->
<select>
<option>Blue</option>
<option>Green</option>
<optgroup label="Darker">
<option>Dark Blue</option>
<option>Dark Green</option>
</optgroup>
</select>
Corrección de URLs rotas con comas en srcset (#8359 por @fisker)
<!-- Input -->
<img
srcset="
_20200401_145009_szrhju_c_scale,w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,w_1400.jpg 1400w"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
>
<!-- Prettier 2.0 -->
<img
srcset="
_20200401_145009_szrhju_c_scale,
w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,
w_1400.jpg 1400w
"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
/>
<!-- Prettier 2.1 -->
<img
srcset="
_20200401_145009_szrhju_c_scale,w_200.jpg 200w,
_20200401_145009_szrhju_c_scale,w_1400.jpg 1400w
"
src="_20200401_145009_szrhju_c_scale,w_1400.jpg"
/>
Compatibilidad con <script type="text/html> (#8371 por @sosukesuzuki)
<!-- Input -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>
<!-- Prettier 2.0 -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>
<!-- Prettier 2.1 -->
<script type="text/html">
<div>
<p>foo</p>
</div>
</script>
Compatibilidad con front matter con detección dinámica de lenguaje (#8381 por @fisker)
Soporte para detección dinámica de lenguaje en front matter, también disponible para los parsers de css, less, scss y markdown.
<!-- Input -->
---my-awsome-language
title: Title
description: Description
---
<h1>
prettier</h1>
<!-- Prettier 2.0 -->
---my-awsome-language title: Title description: Description ---
<h1>
prettier
</h1>
<!-- Prettier 2.1 -->
---my-awsome-language
title: Title
description: Description
---
<h1>
prettier
</h1>
No conservar saltos de línea alrededor de contenido de solo texto (#8614 por @fisker)
Anteriormente, Prettier siempre preservaba saltos de línea alrededor de nodos en línea (elementos en línea, texto, interpolaciones). En general, Prettier intenta evitar depender del formato original siempre que sea posible, pero hay al menos dos casos donde colapsar nodos en línea en una sola línea es indeseable: contenido tipo lista y construcciones condicionales (ej. v-if/v-else en Vue). No se encontró una forma efectiva de detectar estos casos, por lo que se optó por este compromiso. Sin embargo, resultó que para contenido exclusivamente textual esta flexibilidad era innecesaria y solo producía un formato inconsistentemente confuso.
<!-- Input -->
<div>
Hello, world!
</div>
<div>
Hello, {{ username }}!
</div>
<!-- Prettier 2.0 -->
<div>
Hello, world!
</div>
<div>Hello, {{ username }}!</div>
<!-- Prettier 2.1 -->
<div>Hello, world!</div>
<div>Hello, {{ username }}!</div>
Reconocimiento de etiquetas HTML conocidas (#8621 por @fisker)
<!-- Input -->
<div>before<details><summary>summary long long long long </summary>details</details>after</div>
<div>before<dialog open>dialog long long long long long long long long </dialog>after</div>
<div>before<object data="horse.wav"><param name="autoplay" value="true"/><param name="autoplay" value="true"/></object>after</div>
<!-- Prettier 2.0 -->
<div>
before<details><summary>summary long long long long </summary>details</details
>after
</div>
<div>
before<dialog open>dialog long long long long long long long long </dialog
>after
</div>
<div>
before<object data="horse.wav"
><param name="autoplay" value="true" /><param
name="autoplay"
value="true" /></object
>after
</div>
<!-- Prettier 2.1 -->
<div>
before
<details>
<summary>summary long long long long</summary>
details
</details>
after
</div>
<div>
before
<dialog open>dialog long long long long long long long long</dialog>
after
</div>
<div>
before<object data="horse.wav">
<param name="autoplay" value="true" />
<param name="autoplay" value="true" /></object
>after
</div>
Corregir formato de elementos con elemento vacío como último hijo (#8643 por @ikatyang)
<!-- Input -->
<video controls width="250">
<source src="/media/examples/flower.webm"
type="video/webm">
<source src="/media/examples/flower.mp4"
type="video/mp4"
></video>text after
<!-- Prettier 2.0 -->
<video controls width="250">
<source src="/media/examples/flower.webm" type="video/webm" />
<source src="/media/examples/flower.mp4" type="video/mp4" /></video
>text after
<!-- Prettier 2.1 -->
<video controls width="250">
<source src="/media/examples/flower.webm" type="video/webm" />
<source src="/media/examples/flower.mp4" type="video/mp4" /></video
>text after
Vue
Mejorar formato de bloques raíz en SFC de Vue (#8023 por @sosukesuzuki, #8465 por @fisker)
Soporte para formatear todos los bloques de lenguaje (incluyendo bloques personalizados con atributo lang) usando parsers integrados y plugins.
<!-- Input -->
<template lang="pug">
div.text( color = "primary", disabled ="true" )
</template>
<i18n lang="json">
{
"hello": 'prettier',}
</i18n>
<!-- Prettier 2.0 -->
<template lang="pug">
div.text( color = "primary", disabled ="true" )
</template>
<i18n lang="json">
{
"hello": 'prettier',}
</i18n>
<!-- Prettier 2.1 -->
<template lang="pug">
.text(color="primary", disabled="true")
</template>
<i18n lang="json">
{
"hello": "prettier"
}
</i18n>
Se requiere @prettier/plugin-pug para este ejemplo.
Mejorar análisis de bloques personalizados (#8153 por @sosukesuzuki)
<!-- Input -->
<custom lang="javascript">
const foo = "</";
</custom>
<!-- Prettier 2.0 -->
SyntaxError: Unexpected character """ (2:19)
[error] 1 | <custom lang="javascript">
[error] > 2 | const foo = "</";
[error] | ^
[error] 3 | </custom>
<!-- Prettier 2.1 -->
<custom lang="javascript">
const foo = "</";
</custom>
Corregir formato roto con etiquetas HTML en mayúsculas (#8280 por @fisker)
<!-- Input -->
<!doctype html><HTML></HTML>
<!-- Prettier 2.0 -->
<!DOCTYPE html>><HTML></HTML>
<!-- Prettier 2.1 -->
<!DOCTYPE html><HTML></HTML>
Corregir formato inadecuado para template de una línea en SFC de Vue (#8325 por @sosukesuzuki)
<!-- Input -->
<template><p>foo</p><div>foo</div></template>
<!-- Prettier 2.0 -->
<template
><p>foo</p>
<div>foo</div></template
>
<!-- Prettier 2.1 -->
<template>
<p>foo</p>
<div>foo</div>
</template>
Soporte para plantillas DOM de Vue (#8326 por @sosukesuzuki)
Al usar el parser de Vue para HTML, analizar plantillas como HTML.
<!-- Input -->
<!DOCTYPE html>
<html>
<body STYLE="color: #333">
<DIV id="app">
<DIV>First Line</DIV><DIV>Second Line</DIV>
</DIV>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {}
},
});
</script>
</body>
</html>
<!-- Prettier 2.0 -->
<!DOCTYPE html>
<html>
<body STYLE="color: #333">
<DIV id="app"> <DIV>First Line</DIV><DIV>Second Line</DIV> </DIV>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {};
},
});
</script>
</body>
</html>
<!-- Prettier 2.1 -->
<!DOCTYPE html>
<html>
<body style="color: #333">
<div id="app">
<div>First Line</div>
<div>Second Line</div>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {};
},
});
</script>
</body>
</html>
Mejorar formato de etiquetas HTML en mayúsculas en plantillas DOM (#8337 por @sosukesuzuki)
<!-- Input -->
<!DOCTYPE html><HTML>
<body>
<div v-if="foo === 'foo'">
</div>
<script>
new Vue({el: '#app'})
</script>
</body>
</HTML>
<!-- Prettier 2.0 -->
<!DOCTYPE html>
<HTML>
<body>
<div v-if="foo === 'foo'">
</div>
<script>
new Vue({el: '#app'})
</script>
</body>
</HTML>
<!-- Prettier 2.1 -->
<!DOCTYPE html>
<HTML>
<body>
<div v-if="foo === 'foo'"></div>
<script>
new Vue({ el: "#app" });
</script>
</body>
</HTML>
Corregir formato de interpolaciones entre paréntesis (#8747 por @fisker)
<!-- Input -->
<template>
<span>{{(a|| b)}} {{z&&(a&&b)}}</span>
</template>
<!-- Prettier 2.0 -->
<template>
<span>{{(a|| b)}} {{z&&(a&&b)}}</span>
</template>
<!-- Prettier 2.1 -->
<template>
<span>{{ a || b }} {{ z && a && b }}</span>
</template>
Corregir valor abreviado de slots nombrados sin formato (#8839 por @wenfangdu)
<!-- Input -->
<template>
<div #default="{foo:{bar:{baz}}}"></div>
</template>
<!-- Prettier 2.0 -->
<template>
<div #default="{foo:{bar:{baz}}}"></div>
</template>
<!-- Prettier 2.1 -->
<template>
<div #default="{ foo: { bar: { baz } } }"></div>
</template>
Angular
Corrección del encadenamiento opcional con propiedades computadas y manejo de this (#8253 por @thorn0, #7942 por @fisker, correcciones en angular-estree-parser por @ikatyang)
<!-- Input -->
{{ a?.b[c] }}
{{ a ( this )}}
<!-- Prettier 2.0 -->
{{ (a?.b)[c] }}
{{ a ( this )}}
<!-- Prettier 2.1 -->
{{ a?.b[c] }}
{{ a(this) }}
Conservar paréntesis alrededor de pipes en objetos literales para compatibilidad con AngularJS 1.x (#8254 por @thorn0)
<!-- Input -->
<div ng-style="{ 'color': ('#222' | darken)}"></div>
<!-- Prettier 2.0 -->
<div ng-style="{ color: '#222' | darken }"></div>
<!-- Prettier 2.1 -->
<div ng-style="{ 'color': ('#222' | darken)}"></div>
Handlebars (alfa)
Respetar opción singleQuote en valores de atributos más complejos que texto simple (#8375 por @dcyriller)
{{!-- Input --}}
<a href='/{{url}}'></a>
<a href="/{{url}}"></a>
<a href='url'></a>
<a href="url"></a>
{{!-- Prettier 2.0 --}}
<a href="/{{url}}"></a>
<a href="/{{url}}"></a>
<a href='url'></a>
<a href='url'></a>
{{!-- Prettier 2.1 --}}
<a href='/{{url}}'></a>
<a href='/{{url}}'></a>
<a href='url'></a>
<a href='url'></a>
Corregir formato de componentes clásicos dentro de elementos (#8593 por @mikoscz)
{{!-- Input --}}
<div>
{{classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>
{{!-- Prettier 2.0 --}}
<div>
{{
classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>
{{!-- Prettier 2.1 --}}
<div>
{{classic-component-with-many-properties
class="hello"
param=this.someValue
secondParam=this.someValue
thirdParam=this.someValue
}}
</div>
Admitir escape de llaves con barra invertida (#8634 por @dcyriller)
{{!-- Input --}}
\{{mustache}}
\\{{mustache}}
\\\{{mustache}}
{{!-- Prettier 2.0 --}}
{{mustache}}
\{{mustache}}
\\{{mustache}}
{{!-- Prettier 2.1 --}}
\{{mustache}}
\\{{mustache}}
\\\{{mustache}}
Dar formato solo a nombres de clase en atributos (#8677 por @dcyriller)
{{!-- Input --}}
<div class=' class '></div>
<div title=' other attribute '></div>
{{!-- Prettier 2.0 --}}
<div class="class"></div>
<div title="other attribute"></div>
{{!-- Prettier 2.1 --}}
<div class="class"></div>
<div title=" other attribute "></div>
GraphQL
Mejorar ajuste de directivas de fragmentos GraphQL (#7721 por @sasurau4)
# Input
fragment TodoList_list on TodoList @argumentDefinitions(
count: {type: "Int", defaultValue: 10},
) {
title
}
# Prettier 2.0
fragment TodoList_list on TodoList
@argumentDefinitions(count: { type: "Int", defaultValue: 10 }) {
title
}
# Prettier 2.1
fragment TodoList_list on TodoList
@argumentDefinitions(count: { type: "Int", defaultValue: 10 }) {
title
}
Corregir comentarios entre interfaces (#8006 por @fisker)
# Input
type Type1 implements
A &
# comment 1
B
# comment 2
& C {a: a}
# Prettier 2.0
type Type1 implements A & # comment 1
B & # comment 2
C {
a: a
}
# Prettier 2.0 (Second format)
type Type1 implements A & B & C { # comment 1 # comment 2
a: a
}
# Prettier 2.1
type Type1 implements A &
# comment 1
B &
# comment 2
C {
a: a
}
Permitir interfaces que implementen otras interfaces (#8007 por @fisker)
Ver "RFC: Permitir interfaces que implementen otras interfaces"
# Input
interface Resource implements Node {
id: ID!
url: String
}
# Prettier 2.0
interface Resource {
id: ID!
url: String
}
# Prettier 2.1
interface Resource implements Node {
id: ID!
url: String
}
Markdown
Actualizar remark-parse a v8 (#8140 por @saramarcondes, @fisker, @thorn0)
remark, el analizador de Markdown que usa Prettier, recibió una actualización muy esperada (5.0.0 → 8.0.2, ver registro de cambios de remark). Esto corrigió muchos errores antiguos, especialmente relacionados con análisis de elementos de lista indentados con tabulaciones.
Nota: La nueva versión es más estricta al analizar notas al pie, una extensión sintáctica no definida en especificaciones. Antes, Prettier analizaba (y generaba, según --tab-width) notas al pie multilínea indentadas con cualquier espacio. Ahora solo reconoce notas al pie multilínea indentadas con 4 espacios. Este cambio no se considera rompedor por ser sintaxis no estándar, pero si la usas, antes de actualizar Prettier podrías usar la versión anterior con --tab-width=4 para compatibilizar tus notas al pie.
Formatear correctamente oraciones CJK con Selector de Variación (#8511 por @ne-sachirou)
<!-- Input -->
麻󠄁羽󠄀‼️
<!-- Prettier 2.0 -->
麻 󠄁 羽 󠄀 ‼️
<!-- Prettier 2.1 -->
麻󠄁羽󠄀‼️
YAML
Solución de formato inestable con prettier-ignore (#8355 por @fisker)
# Input
# prettier-ignore
---
prettier: true
...
hello: world
# Prettier 2.0
# prettier-ignore
---
prettier: true
---
hello: world
# Prettier 2.0 (Second format)
# prettier-ignore
---
prettier: true
---
hello: world
# Prettier 2.1
# prettier-ignore
---
prettier: true
---
hello: world
Preservar líneas en blanco en comentarios (#8356 por @fisker)
# Input
a:
- a: a
# - b: b
# - c: c
- d: d
b:
- a: a
# - b: b
# - c: c
# Prettier 2.0
a:
- a: a
# - b: b
# - c: c
- d: d
b:
- a: a
# - b: b
# - c: c
# Prettier 2.1
a:
- a: a
# - b: b
# - c: c
- d: d
b:
- a: a
# - b: b
# - c: c
Actualización de yaml y yaml-unist-parser (#8386 por @fisker, correcciones en yaml-unist-parser por @ikatyang)
-
yaml: Añadido error explícito para escalares de bloque con líneas vacías iniciales con mayor indentación -
yaml-unist-parser: fix: sin falsos positivos para la posición del marcador final de cabecera de documento
# Input
# --- comments ---
# Prettier 2.0
--- # --- comments ---
# Prettier 2.1
# --- comments ---
# Input
empty block scalar: >
# comment
# Prettier 2.0
empty block scalar: >
# comment
# Prettier 2.1
SyntaxError: Block scalars with more-indented leading empty lines must use an explicit indentation indicator (1:21)
> 1 | empty block scalar: >
| ^
> 2 |
| ^^
> 3 | # comment
| ^^^^^^^^^^^
Solución de error en sintaxis YAML Inline Extend (#8888 por @fisker, @evilebottnawi, correcciones en yaml-unist-parser por @ikatyang)
# Input
foo:
<<: &anchor
K1: "One"
K2: "Two"
bar:
<<: *anchor
K3: "Three"
# Prettier 2.0
SyntaxError: Merge nodes can only have Alias nodes as values (2:2)
1 | foo:
> 2 | <<: &anchor
| ^^^^^^^^^^^
> 3 | K1: "One"
| ^^^^^^^^^^^^
> 4 | K2: "Two"
| ^^^^^^^^^^^^
> 5 |
| ^
6 | bar:
7 | <<: *anchor
8 | K3: "Three"
# Prettier 2.1
foo:
<<: &anchor
K1: "One"
K2: "Two"
bar:
<<: *anchor
K3: "Three"
API
Añadir parsers de plugins a la opción parser (#8390 por @thorn0)
Cuando un plugin define un lenguaje, los parsers especificados para este lenguaje ahora se añaden automáticamente a la lista de valores válidos de la opción parser.
Esto puede ser útil para integraciones en editores u otras aplicaciones que necesiten una lista de parsers disponibles.
npm install --save-dev --save-exact prettier @prettier/plugin-php
const hasPhpParser = prettier
.getSupportInfo()
.options.find((option) => option.name === "parser")
.choices.map((choice) => choice.value)
.includes("php"); // false in Prettier 2.0, true in Prettier 2.1
Corrección en prettier.getFileInfo() (#8548, #8551, #8585 por @fisker)
-
Al pasar
{resolveConfig: true},inferredParserdebe ser el parser resuelto desde el archivo de configuración; versiones anteriores podían devolver resultados incorrectos para archivos compatibles con parsers integrados. -
Al pasar
{resolveConfig: true}y{ignorePath: "a/file/in/different/dir"}, el resultado deinferredParserpodía ser incorrecto. -
Si la
filePathproporcionada es ignorada,inferredParseres ahora siemprenull.
$ echo {"parser":"flow"}>.prettierrc
$ node -p "require('prettier').getFileInfo.sync('./foo.js', {resolveConfig: true})"
# Prettier 2.0
# { ignored: false, inferredParser: 'babel' }
# Prettier 2.1
# { ignored: false, inferredParser: 'flow' }
$ echo ignored.js>>.prettierignore
$ node -p "require('prettier').getFileInfo.sync('./ignored.js')"
# Prettier 2.0
# { ignored: true, inferredParser: 'babel' }
# Prettier 2.1
# { ignored: true, inferredParser: null }
Corrección en la resolución de editorConfig para archivos en directorios profundos (#8591 por @fisker)
Versiones anteriores no podían encontrar .editorconfig para archivos en directorios profundos (profundidad mayor a 9 desde la raíz del proyecto, ver #5705).
Soporte para archivos de configuración .cjs y .json5 (#8890, #8957 por @fisker)
Se añadieron nuevos formatos de archivos de configuración:
-
.prettierrc.json5 -
.prettierrc.cjs -
prettier.config.cjs
Corrección del formato de rango incorrecto en archivos con BOM (#8936 por @fisker)
Cuando los archivos incluyen BOM, en versiones anteriores el rango real se calculaba incorrectamente.
const text = "\uFEFF" + "foo = 1.0000;bar = 1.0000;";
// ^^^^^^^^^^^^^ Range
const result = require("prettier")
.format(text, {
parser: "babel",
rangeStart: 1,
rangeEnd: 13,
})
// Visualize BOM
.replace("\uFEFF", "<<BOM>>")
// Visualize EOL
.replace("\n", "<<EOL>>");
console.log(result);
// Prettier 2.0
// -> <<BOM>>foo = 1.0;<<EOL>>bar = 1.0;
// ^^^^^^^^^ This part should not be formatted
// Prettier 2.1
// -> <<BOM>>foo = 1.0;bar = 1.0000;
CLI
Corrección de nombres de archivos con caracteres CJK o emojis que no se ignoraban correctamente (#8098 por @fisker)
// Prettier 2.0
$ echo "dir" > .prettierignore
$ prettier **/*.js -l
dir/😁.js
dir/中文.js
not-ignored.js
// Prettier 2.1
$ echo "dir" > .prettierignore
$ prettier **/*.js -l
not-ignored.js
--file-info respeta el .prettierrc y --no-config (#8586, #8830 por @fisker)
$ echo {"parser":"ninja"}>.prettierrc
# Prettier 2.0
$ prettier --file-info file.js
# { "ignored": false, "inferredParser": "babel" }
$ prettier --file-info file.js --no-config
# { "ignored": false, "inferredParser": "babel" }
# Prettier 2.1
$ prettier --file-info file.js
# { "ignored": false, "inferredParser": "ninja" }
$ prettier --file-info file.js --no-config
# { "ignored": false, "inferredParser": "babel" }
Se agregó la bandera --ignore-unknown (alias -u) (#8829 por @fisker)
# Prettier 2.0
npx prettier * --check
Checking formatting...
foo.unknown[error] No parser could be inferred for file: foo.unknown
All matched files use Prettier code style!
# Prettier 2.1
npx prettier * --check --ignore-unknown
Checking formatting...
All matched files use Prettier code style!
Se agregó el alias -w para la opción --write (#8833 por @fisker)
# Prettier 2.0
$ prettier index.js -w
[warn] Ignored unknown option -w. Did you mean -_?
"use strict";
module.exports = require("./src/index");
# Prettier 2.1
$ prettier index.js -w
index.js 30ms
Se dejó de sugerir -_ para opciones desconocidas (#8934 por @fisker)
# Prettier 2.0
$ prettier foo.js -a
[warn] Ignored unknown option -a. Did you mean -_?
# Prettier 2.1
$ prettier foo.js -a
[warn] Ignored unknown option -a. Did you mean -c?
