Saltar al contenido principal

Prettier 1.8: Soporte para Markdown

· 16 min de lectura
Traducción Beta No 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 añade soporte para Markdown, una nueva bandera --insert-pragma, corrige varios problemas de formato, añade soporte para algunos operadores nuevos experimentales y mejora la integración con editores.

Destacados

Soporte para Markdown

Soporte para markdown (#2943) por @ikatyang

¡Ahora puedes ejecutar Prettier en archivos Markdown! 🎉

La implementación cumple ampliamente con la especificación CommonMark y está respaldada por el excelente paquete remark-parse.

Ajuste de líneas

Una de las características principales de Prettier es su capacidad para ajustar el código a un ancho de línea específico. Esto también se aplica a Markdown, lo que significa que puedes mantener archivos Markdown limpios y de 80 caracteres de ancho sin tener que reajustar manualmente los saltos de línea al agregar o eliminar palabras.

Entrada:

Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honour to meet you and you may call me V.

Salida:

Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim
and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity,
is a vestige of the vox populi, now vacant, vanished. However, this valourous
visitation of a bygone vexation stands vivified and has vowed to vanquish these
venal and virulent vermin vanguarding vice and vouchsafing the violently vicious
and voracious violation of volition! The only verdict is vengeance; a vendetta
held as a votive, not in vain, for the value and veracity of such shall one day
vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage
veers most verbose, so let me simply add that it's my very good honour to meet
you and you may call me V.

Nota: Estamos considerando añadir una opción para esto, consulta #3183 para la discusión. Actualización: Hemos añadido una opción en 1.8.2 llamada --no-prose-wrap

Nota para usuarios CJK: Si tu renderizador de markdown no soporta finales de línea CJK, deberás usar plugins como markdown-it-perfect-newline-for-cjk, hexo-filter-fix-cjk-spacing, etc. para eliminar espacios adicionales.

// Source
一二三
四五六
七八九

// Rendered content with unsupported renderer
一二三 四五六 七八九

// Rendered content with supported renderer or via plugin
一二三四五六七八九

Formateo de código

Gracias al "multiparser" genérico de Prettier, ¡Prettier formateará bloques de código en Markdown! Usamos el código de lenguaje proporcionado con el bloque de código para determinar el lenguaje, permitiéndonos formatear cualquier lenguaje que Prettier soporte (incluyendo el propio Markdown, si te interesa).

Entrada:

```js
reallyUgly (
javascript
)
```

```css
.h1 { color : red }
```

Salida:

```js
reallyUgly(javascript);
```

```css
.h1 {
color: red;
}
```

Nota: En algunos casos puedes querer excluir tu código de Markdown del formateo. Al igual que en otros lenguajes, puedes usar un comentario de ignorar antes del bloque de código:

<!-- prettier-ignore -->
```js
ugly ( code ) ;
```

Listas

Al reorganizar elementos de lista, Prettier corregirá automáticamente todos los números después de ejecutarse.

Listas en Markdown

Nota: Puedes desactivar este comportamiento usando 1. para todos los elementos de lista si prefieres optimizar para diferencias más limpias.

Tablas

Las tablas también se ajustarán automáticamente para adaptarse a su contenido. Esto sería completamente inmantenible sin una herramienta automatizada.

Tablas en Markdown

Markdown-en-JS

Usando literales de plantilla etiquetados como md o markdown, puedes formatear código markdown dentro de JavaScript.

const markdown = md`
# heading

1. list item
`;

CLI

Añadir opción para insertar @format en el primer docblock si está ausente (#2865) por @samouri

En la versión 1.7, añadimos una opción llamada --require-pragma para requerir que los archivos contengan el pragma /** @format */ para ser formateados. Para añadir este pragma a un gran conjunto de archivos, ahora puedes usar la bandera --insert-pragma.

prettier --write "folder/**/*.js" --insert-pragma

Añadir opción --loglevel (#2992) por @ikatyang

Esta práctica característica te permite activar (o desactivar) el registro de logs de Prettier. Además, hemos mejorado sustancialmente el registro de logs desde la versión 1.7.

$ prettier --loglevel=debug blarg
$ ./bin/prettier.js --loglevel=debug blarg
[debug] normalized argv: {"_":["blarg"],"bracket-spacing":false,"color":true,"debug-check":false,"debug-print-doc":false,"flow-parser":false,"insert-pragma":false,"jsx-bracket-same-line":false,"list-different":false,"require-pragma":false,"semi":false,"single-quote":false,"stdin":false,"use-tabs":false,"version":false,"with-node-modules":false,"write":false,"loglevel":"debug","ignore-path":".prettierignore","config-precedence":"cli-override"}
[error] No matching files. Patterns tried: blarg !**/node_modules/** !./node_modules/**

JavaScript

Corregir sangría para comentarios JSDoc (#2470) por @maxdeviant

Este ha sido un problema conocido en Prettier desde hace tiempo. Al formatear código que resulta en un cambio de nivel de sangría, los comentarios JSDoc quedaban desalineados. ¡Nos complace informar que esto ya está solucionado!

// Before
function theFunction2(action$, store) {
/*
* comments
*/
return true;
}

// After
function theFunction2(action$, store) {
/*
* comments
*/
return true;
}

Implementar operadores pipeline y nullish-coalescing (#3036) por @azz

Hemos añadido soporte para dos nuevos operadores propuestos en Prettier: el operador pipeline y el operador nullish coalescing.

El operador pipeline es actualmente una propuesta en etapa 1 (stage one).

Esta propuesta introduce un nuevo operador |> similar a los de F#, OCaml, Elixir, Elm, Julia, Hack y LiveScript, así como a las tuberías UNIX. Es una forma compatible con versiones anteriores de simplificar llamadas encadenadas de funciones de manera legible y funcional, y proporciona una alternativa práctica a extender prototipos integrados.

// Before
let result = exclaim(capitalize(doubleSay("hello")));

// After
let result = "hello"
|> doubleSay
|> capitalize
|> exclaim;

El operador nullish coalescing es otra propuesta en etapa 1 (stage one).

Al realizar acceso opcional a propiedades en una estructura anidada junto con el operador de encadenamiento opcional, a menudo se desea proporcionar un valor predeterminado si el resultado de ese acceso es null o undefined.

Este operador es similar a || excepto que solo evalúa el lado derecho si el izquierdo es undefined o null, no "", 0, NaN, etc.

const foo = object.foo ?? "default";

Mejora en saltos de línea para expresiones en literales de plantilla (#3124) por @duailibe

Este era otro problema conocido en Prettier: al imprimir un literal de plantilla con expresiones internas que superaban el ancho de línea, envolvía el código en lugares extraños dentro de las expresiones. Ahora, si Prettier necesita insertar un salto de línea, debería ocurrir justo entre ${ y }.

// Before
const description = `The value of the ${cssName} css of the ${this
._name} element`;

const foo = `mdl-textfield mdl-js-textfield ${className} ${content.length > 0
? "is-dirty"
: ""} combo-box__input`;

// After
const description = `The value of the \${cssName} css of the \${
this._name
} element`;

const foo = `mdl-textfield mdl-js-textfield ${className} ${
content.length > 0 ? 'is-dirty' : ''
} combo-box__input`

JSX

No alinear llave de cierre } para atributos de funciones flecha (#3110) por @duailibe

Para alinearnos más con la guía de estilo de Airbnb y dado que nunca fue intencional imprimirlo así, hemos movido la } a la siguiente línea en JSX. Esto facilita los diffs y hace más sencillo mover código desplazando líneas en el editor.

// Before
<BookingIntroPanel
logClick={data =>
doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)}
/>;

// After
<BookingIntroPanel
logClick={data =>
doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
}
/>;

Otros cambios

JavaScript

Mejora en la detección de fábricas para múltiples elementos (#3112) por @vjeux

Existía un error en la heurística que Prettier usa para determinar si una expresión es una fábrica. Ahora funciona correctamente con expresiones de miembro más largas.

// Before
window.FooClient
.setVars({
locale: getFooLocale({ page }),
authorizationToken: data.token
})
.initVerify("foo_container");

// After
window.FooClient.setVars({
locale: getFooLocale({ page }),
authorizationToken: data.token
}).initVerify("foo_container");

Manejo de comentarios entre el nombre de función y el paréntesis (#2979) por @azz

Imprimir comentarios en el lugar correcto es un desafío interminable 😉. Esta corrección garantiza que los comentarios junto a nombres de función se reimpriman correctamente.

// Before
function f(/* comment*/ promise) {}

// After
function f /* comment*/(promise) {}

Soporte para CallExpressions secuenciales en cadenas de miembros (#2990) por @chrisvoll

Las cadenas de miembros son una de las partes más complejas de Prettier. Este PR corrige un problema donde llamadas repetidas evitaban que el siguiente método saltara a la siguiente línea.

// Before
wrapper
.find("SomewhatLongNodeName")
.prop("longPropFunctionName")().then(function() {
doSomething();
});

// After
wrapper
.find("SomewhatLongNodeName")
.prop("longPropFunctionName")()
.then(function() {
doSomething();
});

Consideración de líneas vacías en cadenas largas de llamadas a miembros (#3035) por @jackyho112

Previamente, Prettier eliminaba todos los saltos de línea dentro de una cadena de miembros. Ahora conservamos hasta uno si existe en el código fuente. Esto es útil para APIs fluidas que deseas dividir en múltiples líneas.

angular
.module("AngularAppModule")

// Constants.
.constant("API_URL", "http://localhost:8080/api")

// App configuration.
.config(appConfig)
.run(appRun);

Corrección de argumento inicial abandonado al romper líneas (#3079) por @mutdmour

Soluciona un problema donde, debido a nuestro comportamiento especial de objetos en línea, faltaba la indentación en la llamada a función.

// Before
db.collection("indexOptionDefault").createIndex({ a: 1 },
{
indexOptionDefaults: true
},
function(err) {
// code
});

// After
db.collection("indexOptionDefault").createIndex(
{ a: 1 },
{
indexOptionDefaults: true
},
function(err) {
// code
}
);

Romper paréntesis para binarios en expresiones de miembro (#2958) por @duailibe

De manera similar, existía otro caso límite donde faltaba indentación en expresiones lógicas. Esto también está corregido.

// Before
const someLongVariable = (idx(
this.props,
props => props.someLongPropertyName
) || []
).map(edge => edge.node);

// After
const someLongVariable = (
idx(this.props, props => props.someLongPropertyName) || []
).map(edge => edge.node);

Prevenir ruptura de MemberExpression dentro de NewExpression (#3075) por @duailibe

Existen muchas formas de romper una línea. Algunas se ven peor que otras. Romper en este caso particular resultaba muy extraño, ¡así que se ha corregido!

// Before
function functionName() {
if (true) {
this._aVeryLongVariableNameToForceLineBreak = new this
.Promise((resolve, reject) => {
// do something
});
}
}

// After
function functionName() {
if (true) {
this._aVeryLongVariableNameToForceLineBreak = new this.Promise(
(resolve, reject) => {
// do something
}
);
}
}

Corrección de accesores de array en cadenas de métodos (#3137) por @duailibe

En una cadena de métodos, dividimos líneas agrupando elementos juntos, y el acceso a arrays debe imprimirse al final del grupo en lugar del principio.

// Before
find('.org-lclp-edit-copy-url-banner__link')
[0].getAttribute('href')
.indexOf(this.landingPageLink)

// After
find('.org-lclp-edit-copy-url-banner__link')[0]
.getAttribute('href')
.indexOf(this.landingPageLink)

Flow y TypeScript

Corrección de indentación en tipos de objeto de intersección (#3074) por @duailibe

Era un error menor de alineación en tipos de intersección, que ahora está solucionado.

// Before
type intersectionTest = {
propA: X
} & {
propB: X
} & {
propC: X
} & {
propD: X
};

// After
type Props = {
propA: X
} & {
propB: X
} & {
propC: X
} & {
propD: X
};

Conservar paréntesis alrededor de TSAsExpression en ConditionalExpression (#3053) por @azz

Faltaba un caso donde necesitábamos conservar los paréntesis con las aserciones as de TypeScript. Esto ya está corregido.

// Before
aValue as boolean ? 0 : -1;

// After
(aValue as boolean) ? 0 : -1;

JSX

Colapsar múltiples espacios en blanco de JSX (#2973) por @karl

Esto soluciona el problema donde el formato JSX ocasionalmente necesitaba ejecutarse dos veces para estabilizarse. Ocurría cuando tenías múltiples elementos de espacio en JSX o espacio en JSX seguido de un espacio adicional.

// Before
<div>
{" "} <Badge src={notificationIconPng} />
</div>;

// After
<div>
{" "}
<Badge src={notificationIconPng} />
</div>

No imprimir corchete JSX en la misma línea cuando tiene comentarios posteriores (#3088) por @azz

Esto era un problema con la opción --jsx-bracket-same-line. Resulta que no siempre puedes poner el corchete en la misma línea...

// Input
<div
// comment
>
{foo}
</div>

// Before
<div>
// comment
{foo}
</div>;

// After
<div
// comment
>
{foo}
</div>;

CSS

Conservar saltos de línea en declaraciones grid (#3133) por @duailibe

Prettier ahora conservará los saltos de línea incluidos en el código fuente al formatear las reglas grid y grid-template-*, ya que es importante mantenerlos en líneas separadas, pero sigue aplicando el formato como en otras reglas (ej. números y comillas).

/* Original Input */
div {
grid:
[wide-start] 'header header header' 200.000px
[wide-end] "footer footer footer" .50fr
/ auto 50.000px auto;
}

/* Before */
div {
grid: [wide-start] "header header header" 200px [wide-end]
"footer footer footer" 0.5fr / auto 50px auto;
}

/* After */
div {
grid:
[wide-start] "header header header" 200px
[wide-end] "footer footer footer" 0.5fr
/ auto 50px auto;
}

SCSS

Formatear mapas SCSS como reglas CSS (#3070) por @asmockler

Resulta que los mapas SCSS se ven mucho mejor cuando se imprimen en múltiples líneas.

// Before
$map: (color: [#111111](https://github.com/prettier/prettier/pull/111111), text-shadow: 1px 1px 0 salmon)

// After
$map: (
color: [#111111](https://github.com/prettier/prettier/pull/111111),
text-shadow: 1px 1px 0 salmon
);

CSS-in-JS

Corregir formato en styled(Foo).attrs(...)`` (#3073) por @existentialism

Prettier ahora formateará el CSS en código styled-components que luce así:

styled(Component).attrs({})`
color: red;
`;

GraphQL

Evitar el formateo de literales de plantilla GraphQL con expresiones (#2975) por @duailibe

Prettier no soporta formatear expresiones JavaScript en GraphQL. Consulta #2640 para seguimiento. Había un bug donde formatear una expresión producía código inválido, así que deshabilitamos completamente el formateo de GraphQL cuando contiene expresiones JavaScript hasta que tengamos soporte completo.

// Before
(invalid code)

// After
graphql(schema, `{ query test { id }} ${fragment}`)

CLI

No usar códigos ANSI si stdout no es una TTY (#2903) por @Narigo

Anteriormente, canalizar la salida de --list-different a otras herramientas era problemático debido a los códigos de color ANSI que usamos para mostrar si un archivo fue modificado. Este PR desactiva el uso de color cuando la salida de Prettier se canaliza a otro proceso.

Configuración

Usar rutas relativas con CLI (#2969) por @ahmedelgabri

Esto soluciona un bug donde pasar una ruta que comienza con ./ a la CLI no coincidía con patrones usados en .prettierignore.

## .prettierignore
path/to/*.js

Tras esta corrección, no se escribirán archivos al ejecutar:

$ prettier --write ./path/to/*.js

Resolver rutas de archivo relativas al archivo de configuración (#3037) por @azz

Esto soluciona un problema donde las anulaciones de .prettierrc, bajo ciertas condiciones, no se respetaban para rutas absolutas con la API resolveConfig.

Núcleo

Respeto al ancho CJK y caracteres combinados (#3003, #3015) por @ikatyang

Ahora los caracteres chinos, japoneses y coreanos (CJK) se consideran de dos caracteres de ancho.

// Before (exceeds print width when CJK characters are 2x monospace chars)
const x = ["中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文"];

// After
const x = [
"中文",
// ...
"中文"
];

##3015 también garantiza que los caracteres combinados (ej. Á) se cuenten como un solo carácter.

Soporte para editores

Implementar getSupportInfo() y usarlo para inferencia (#3033) por @azz

Hemos añadido una nueva función a la API (prettier.getSupportInfo([version])) y la opción CLI --support-info. Esto permite consultar a Prettier para conocer qué lenguajes soporta la versión actual o versiones anteriores. También proporciona información útil como IDs de CodeMirror, tmScopes, etc., que pueden automatizar parte del trabajo realizado con tablas de búsqueda en integraciones de editores de texto.

Internamente, usamos esta información para determinar qué extensiones activan qué analizadores, y soportamos archivos comunes sin extensión como .prettierrc, Jakefile, etc.

## prettier knows that this file is JSON now.
$ prettier --write .prettierrc

Dividir elementos fuente según su lenguaje (#3069) por @CiGit

Esto soluciona un problema en editores que admiten formateo por rangos, donde formatear un objeto causaba que Prettier fallara.


¡Gracias! ❤️

Gracias a todos los que contribuyeron a esta versión, ¡así como a quienes reportaron problemas! Prettier se ha convertido en un software altamente estable en el que mucha gente confía para su código. Tomamos esa confianza con seriedad y corregimos raros problemas que rompen código con máxima prioridad. No podemos solucionar estos problemas si no los conocemos, ¡así que nunca temas crear un issue!