Zum Hauptinhalt springen

Prettier 1.6: Konfigurationsdatei, JSX

· 14 Min. Lesezeit
Inoffizielle Beta-Übersetzung

Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →

Diese Version fügt Unterstützung für Konfigurationsdateien zu Prettier hinzu und bringt wesentliche Verbesserungen bei der JSX-Formatierung.

Besonderer Dank geht an @azz, der das Repository gepflegt und viele Änderungen dieser Version implementiert hat, während ich durch Urlaub und Teamwechsel weniger Zeit für Prettier aufwenden konnte :)

Höhepunkte

Konfiguration

Implementierung von cosmiconfig für Workspace-Konfiguration (#2434) von @azz

Seit der ersten Veröffentlichung von Prettier wurde nach einer .prettierrc-Datei gefragt. Wir strebten stets möglichst wenige Optionen an und wollten vermeiden, dass beim Projektstart eine weitere .dotfile benötigt wird.

Doch tatsächlich benötigen wir eine Konfigurationsmöglichkeit, die mit allen Integrationen synchron gehalten werden kann. Ohne eigene Lösung verlagerte sich das Problem auf die Integrationen, was zu inkompatiblen Ansätzen führte. Daher übernimmt Prettier dies nun selbst.

// .prettierrc
{
"trailingComma": "es5",
"singleQuote": true
}

Weitere Informationen zur Konfigurationsdatei finden Sie im README.

Unterstützung für .prettierignore-Dateien (#2412) von @evilebottnawi

Neben der Konfiguration können Sie eine .prettierignore-Datei erstellen, um Dateien von der Konvertierung auszuschließen.

## .prettierignore
dist/
package.json

JSX

Verbesserte JSX-Formatierung (#2398) von @suchipi

Der letzte große Reibungspunkt bei der Prettier-Einführung betraf die JSX-Formatierung. Wir analysierten alle gemeldeten Probleme und implementierten folgende Änderungen:

  • Pfeilfunktionen, die JSX zurückgeben, erhalten bei Zeilenumbrüchen nun Klammern
// Before
const Component = props =>
<div>
Hello {props.name}!
</div>;

// After
const Component = props => (
<div>
Hello {props.name}!
</div>
);
  • Bedingte Ausdrücke in (oder mit) JSX werden mit Klammern neu formatiert
// Before
<div>
{props.isVisible
? <BaseForm
url="/auth/google"
method="GET"
/>
: <Placeholder />}
</div>;

// After
<div>
{props.isVisible ? (
<BaseForm
url="/auth/google"
method="GET"
/>
) : (
<Placeholder />
)}
</div>
  • JSX in logischen Ausdrücken (|| oder &&) wird bei Zeilenumbrüchen stets in Klammern gesetzt
// Before
<div>
{props.isVisible &&
<BaseForm
url="/auth/google"
method="GET"
/>}
</div>;

// After
<div>
{props.isVisible && (
<BaseForm
url="/auth/google"
method="GET"
/>
)}
</div>

Dies entspricht hoffentlich besser den Schreibgewohnheiten der Community und ermöglicht breitere Prettier-Nutzung ;)

Inline-Darstellung einzelner Ausdrücke in JSX (#2442) von @karl

Ursprünglich respektierten wir bei JSX viele Zeilenumbrüche des Originalcodes. Dies minimierte Änderungen an Codebasen, untergrub jedoch den Wert eines konsistenten Formatierers, da semantisch gleicher Code unterschiedlich dargestellt werden konnte.

Mit jeder Version verschärften wir diese Regeln. Die neueste Entscheidung: Einzelne Kindelemente in JSX-Objekten werden nun stets inline dargestellt.

// Before
return (
<div>
{this.props.test}
</div>
);
return <div>{this.props.test}</div>;

// After
return <div>{this.props.test}</div>;
return <div>{this.props.test}</div>;

Zeilenumbruch nach führendem JSX-Leerraum (#2348) von @karl

Führende Leerräume in JSX stehen nun in eigenständigen Zeilen. Ihre Platzierung vor Tags wirkte zuvor unnatürlich, da sie eine andere "Einrückung" erzeugten.

// Before
<span className="d1">
{' '}<a
href="https://github.schibsted.io/finn/troika"
className="link"
/>
</span>

// After
<span className="d1">
{' '}
<a
href="https://github.schibsted.io/finn/troika"
className="link"
/>
</span>

Weitere Änderungen

JSON

Verwendung von babylon.parseExpression für JSON (#2476) von @josephfrazier

Bisher nutzten wir einen strikten JSON-Parser, der bei Kommentaren oder nachgestellten Kommas Fehler warf. Das war unpraktisch, da viele JSON-Dateien in der Praxis mit JavaScript oder json5 geparst werden, die weniger streng sind. Jetzt haben wir dies gelockert und verwenden den JavaScript-Parser für JSON. Dadurch bleiben vorhandene Kommentare erhalten.

Hinweis: Dies ist rein additiv. Wenn Ihre Originaldatei JSON-konform war, bleibt die Ausgabe gültiges JSON.

// Before
Syntax error

// After
{ /* some comment */ "a": 1 }

JavaScript

Druck von 3 oder mehr verketteten Aufrufen in mehreren Zeilen (#2673) von @azz

Dies war ein langjähriges Problem bei der Formatierung langer Methodenketten. Prettier versuchte alle bis auf den letzten Callback in eine Zeile zu quetschen, was die Lesbarkeit beeinträchtigte. Die Lösung: Bei drei oder mehr Funktionsaufrufen in einer Methodenkette wird immer in mehrere Zeilen umgebrochen.

// Before
Promise.resolve(0).catch(function(err) {}).then(function(res) {
//
});

// After
Promise.resolve(0)
.catch(function(err) {})
.then(function(res) {
//
});

Zusätzliche überwachende Klammern hinzufügen (#2423) von @azz

Klammern sind heikel, da sie nicht zum AST gehören. Prettier ignoriert Ihre Klammern und erzeugt sie neu. Wir haben Edge Cases behoben, wo verkettete Vergleiche mit % gemischt mit * oder / verwirrend waren.

Unverändert bleibt: Überflüssige Klammern bei Grundrechenarten (+-*/) werden entfernt.

// Before
x !== y === z;
x * y % z;

// After
(x !== y) === z;
(x * y) % z;

Implementierung von prettier-ignore innerhalb von JSX (#2487) von @azz

Um Teile von JSX von der Formatierung auszunehmen, kann nun ein Kommentar innerhalb eines JSX-Ausdrucks hinzugefügt werden, der das nächste Element ignoriert.

// Before
<Component>
{/*prettier-ignore*/}
<span ugly format="" />
</Component>

// Before
<Component>
{/*prettier-ignore*/}
<span ugly format='' />
</Component>

prettier-ignore-Kommentare nicht mehr unterdrücken (#2664)

Intern können wir Kommentare generisch unterdrücken und später ausgeben. Dabei wurden prettier-ignore-Kommentare versehentlich komplett entfernt – jetzt behoben.

// Before
push(
<td> :)
</td>,
);

// After
push(
// prettier-ignore
<td> :)
</td>,
);

Korrektur der Einrückung bei do-while-Bedingungen (#2359) von @jsnajdr

Erst nach 6 Monaten wurde gemeldet, dass mehrzeilige while-Bedingungen in do-while-Schleifen falsch formatiert wurden. Bestätigt meine Vermutung, dass dieses Konstrukt selten genutzt wird.

// Before
do {} while (
someVeryLongFunc(
someVeryLongArgA,
someVeryLongArgB,
someVeryLongArgC
)
);

// After
do {} while (
someVeryLongFunc(
someVeryLongArgA,
someVeryLongArgB,
someVeryLongArgC
)
);

Umbruch von Sequenzausdrücken (#2388) von @bakkot

Sequenzausdrücke sind ein weiteres selten genutztes JavaScript-Feature. Die Formatierung bei mehrzeiligen Ausdrücken war bisher suboptimal – jetzt korrigiert :)

// Before
(a = b ? c : "lllllllllllllllllllllll"), (a = b
? c
: "lllllllllllllllllllllll"), (a = b ? c : "lllllllllllllllllllllll"), (a = b
? c
: "lllllllllllllllllllllll"), (a = b ? c : "lllllllllllllllllllllll");

// After
(a = b ? c : 'lllllllllllllllllllllll'),
(a = b ? c : 'lllllllllllllllllllllll'),
(a = b ? c : 'lllllllllllllllllllllll'),
(a = b ? c : 'lllllllllllllllllllllll'),
(a = b ? c : 'lllllllllllllllllllllll')

Entfernung von Leerzeichen am Zeilenende in Kommentaren (#2494) von @azz

Prettier entfernt konsequent überflüssige Leerzeichen. Kommentare blieben bisher verschont, da nutzergeneriert – aber auch sie sollten keine überflüssigen Leerzeichen enthalten :)

// Before
// There is some space here ->______________

// After
// There is some space here ->

Korrektur verschachtelter Kommentare in Klassendekoratoren (#2660, #2661)

Unser Umgang mit Kommentaren innerhalb von Klassendeklarationen war zu einfach: Wir haben alle Kommentare einfach an den Anfang verschoben. Jetzt gehen wir präziser vor und berücksichtigen die Kommentare, die zwischen Decorators und um extends herum stehen.

// Before
// A
// B
// C
@Foo()
@Bar()
class Bar {}

// After
// A
@Foo()
// B
@Bar()
// C
class Bar {}

Verbesserte Formatierung von Bind-Ausdrücken (#2493) von @azz

Bind-Ausdrücke werden bei TC39 diskutiert und wir dachten, wir könnten sie mit Prettier formatieren. Früher sind wir sehr naiv damit umgegangen und haben sie einfach verkettet. Jetzt verwenden wir dieselbe Logik wie für Methodenverkettung mit dem .-Operator. Wir haben auch einige Randfälle behoben, in denen ungültiger Code ausgegeben wurde.

// Before
observable::filter(data => data.someTest)::throttle(() =>
interval(10)::take(1)::takeUntil(observable::filter(data => someOtherTest))
)::map(someFunction);

// After
observable
::filter(data => data.someTest)
::throttle(() =>
interval(10)::take(1)::takeUntil(observable::filter(data => someOtherTest))
)
::map(someFunction);

Unterstützung für optionales Catch-Binding hinzugefügt (#2570) von @existentialism

Bei TC39 wird diskutiert, das Argument von catch(e) optional zu machen. Wir stellen sicher, dass wir es in Prettier unterstützen, falls Entwickler es verwenden.

// Before
Syntax error

// After
try {} catch {}

Unterstützung für die Syntax des optionalen Chaining hinzugefügt (#2572) von @azz

Ein weiterer neuer Vorschlag bei TC39 ist die Syntax für optionales Chaining. Dies ist derzeit ein Stage-1-Vorschlag, daher kann sich die Syntax noch ändern.

obj?.prop       // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call

Korrekte Behandlung der Type-Cast-Syntax des Closure Compilers (#2484) von @yangsu

Kommentare sind knifflig, besonders wenn ihre Bedeutung von ihrer Position abhängt. Wir behandeln nun Kommentare, die als Type Cast für den Closure Compiler verwendet werden, in einem Sonderfall, damit sie ihre Semantik behalten.

// Before
let assignment /** @type {string} */ = getValue();

// After
let assignment = /** @type {string} */ (getValue());

Erste berechnete Eigenschaftssuche in Member-Ketten inline gesetzt (#2670) von @azz

Es sieht ungewöhnlich aus, wenn eine berechnete Eigenschaftssuche in der nächsten Zeile steht, daher haben wir einen Sonderfall hinzugefügt, um sie inline zu setzen.

// Before
data
[key]('foo')
.then(() => console.log('bar'))
.catch(() => console.log('baz'));

// After
data[key]('foo')
.then(() => console.log('bar'))
.catch(() => console.log('baz'));

Flow

Unterstützung für opaque types und export star (#2543, #2542) von @existentialism

Das Flow-Team hat zwei spannende Features mit neuer Syntax eingeführt. Wir unterstützen sie nun in Prettier. Ich persönlich habe opaque types schon seeehr lange erwartet!

// Before
Syntax error

// After
opaque type ID = string;
export type * from "module";

Entfernen unnötiger Anführungszeichen in Schlüsseln von Typobjekten und Interfaces (#2643) von @jackyho112

Das machen wir bei JavaScript-Objekten seit Prettiers Anfängen, hatten es aber für Flow- und TypeScript-Typen vergessen.

// Before
type A = {
"string": "A";
}

// After
type A = {
string: "A";
}

TypeParameter auch bei unären Funktionstypen ausgeben (#2406) von @danwang

Ups, in diesem speziellen Fall haben wir den Generics-Typ weggelassen.

// Before
type myFunction = A => B;

// After
type myFunction = <T>(A) => B;

Klammern um FunctionTypeAnnotation innerhalb von ArrayTypeAnnotation beibehalten (#2561) von @azz

Klammern... eines Tages werden wir sie alle richtig setzen :)

// Before
const actionArray: () => void[] = [];

// After
const actionArray: (() => void)[] = [];

TypeScript

Unterstützung für TypeScript 2.5 RC (#2672) von @azz

TypeScript 2.5 RC wurde kürzlich veröffentlicht, sodass du auch in TypeScript die kommende Syntax für "optionale catch-Bindings" nutzen kannst. 🎉

Namespace-Schlüsselwort nicht bei globaler Deklaration hinzufügen (#2329) von @azz

// Before
namespace global {
export namespace JSX { }
}

// After
global {
export namespace JSX {}
}

Korrektur von <this.Component /> (#2472) von @backus

Dank der untypisierten und toleranten Natur von JavaScript konnten wir undefined an einen String hängen und erhielten interessanten Code als Ergebnis. Für diesen Fall jetzt behoben :)

// Before
<undefined.Author />

// After
<this.Author />

Erlaube von Typ-Assertions ohne Leerzeichen (#2439) von @azz

Wir möchten sicherstellen, dass alle Sonderfälle, die wir für JavaScript und Flow hinzugefügt haben, auch für TypeScript-Konstrukte funktionieren. In diesem Fall sollten Objekte auch ohne Leerzeichen formatiert werden, wenn sie in einen as-Operator eingebettet sind.

// Before
const state = JSON.stringify(
{
next: window.location.href,
nonce,
} as State
);

// After
const state = JSON.stringify({
next: window.location.href,
nonce,
} as State);

Entferne Klammern bei Typ-Assertions in binären Ausdrücken (#2419) von @azz

Meist fügen wir Klammern für Korrektheit hinzu, aber hier waren sie unnötig. Wir entfernen sie nun für saubereren Code :)

// Before
(<x>a) || {};

// After
<x>a || {};

Setze Klammern um Typ-Assertions als LHS in Zuweisungen (#2525) von @azz

Ein weiterer Fall fehlender Klammern. Glücklicherweise treten sie nur noch selten bei extremen Randfällen auf.

// Before
foo.bar as Baz = [bar];

// After
(foo.bar as Baz) = [bar];

Drucke declare für TSInterfaceDeclaration (#2574) von @existentialism

Das Schlüsselwort declare hat bei interface keine Funktion, daher setzten wir es nie. In Deklarationsdateien wirkte es jedoch seltsam, wenn alles declare trug außer Interfaces. Nun geben wir declare aus, wenn es ursprünglich vorhanden war.

// Before
interface Dictionary<T> {
[index: string]: T
}

// After
declare interface Dictionary<T> {
[index: string]: T
}

CSS

Normalisiere Anführungszeichen in CSS (#2624) von @lydell

Für die Erstversion von CSS behielten wir String-Anführungszeichen unverändert. Jetzt respektieren wir die singleQuote-Option von Prettier. Die Herausforderung lag darin, korrekten Code für alle Sonderfälle wie Escapes, Unicode-Zeichen, Emojis und Spezialregeln (z.B. charset, die nur mit doppelten Anführungszeichen funktioniert) zu gewährleisten.

// Before
div {
content: "abc";
}

// After
div {
content: 'abc';
}

Normalisiere Zahlen in CSS (#2627) von @lydell

Ein weiterer Bereich, in dem wir die Logik aus JavaScript wiederverwenden, um die CSS-Formatierung zu verbessern.

// Before
foo {
border: 1px solid rgba(0., 0.0, .0, .3);
}

// After
foo {
border: 1px solid rgba(0, 0, 0, 0.3);
}

Setze Anführungszeichen um nicht-quotierte CSS-Attributwerte in Selektoren (#2644) von @lydell

Die Regeln für Anführungszeichen bei Attributen sind komplex – daher setzen wir sie nun konsequent.

// Before
a[id=test] {}

// After
a[id="test"] {}

Füge Unterstützung für css-Schlüsselwort hinzu (#2337) von @zanza00

// Before
const header = css`.top-bar {background: black;margin: 0;position: fixed;}`

// After
const header = css`
.top-bar {
background: black;
margin: 0;
position: fixed;
}
`;

Unterstützung für styled-components mit bestehenden Komponenten (#2552, #2619) von @azz

styled-components bietet viele verschiedene Varianten, um Template-Literals als CSS zu kennzeichnen. Es ist nicht ideal, dass wir all diese Methoden in Prettier abbilden müssen, aber da wir damit angefangen haben, sollten wir es auch richtig machen.

styled(ExistingComponent)`
css: property;
`;

styled.button.attr({})`
border: rebeccapurple;
`;

Leerzeichen in Nachfahren-Kombinatoren entfernen (#2411) von @azz

Die von uns verwendeten CSS-Parser liefern keinen 100% semantischen Baum: In vielen Fällen geben sie einfach die ursprüngliche Eingabe zurück. Es liegt an uns, dies zu bereinigen und gleichzeitig Korrektheit zu gewährleisten. Hier haben wir Leerzeichen zwischen Selektoren ursprünglich belassen, aber wir wissen, dass es korrekt ist, sie stets durch ein einzelnes Leerzeichen zu ersetzen.

// Before
.hello

.how-you-doin {
height: 42;
}

// After
.hello .how-you-doin {
height: 42;
}

BOM vor dem Parsen entfernen (#2373) von @azz

BOM bereitet mir immer noch Alpträume aus früheren Zeiten. Zum Glück ist es 2017 kein großes Problem mehr, da die meisten Tools damit umgehen können. Danke an @azz für die Behebung eines Randfalls beim CSS-Parsing.

// Before
[BOM]/* Block comment *
html {
content: "#{1}";
}
// After
[BOM]/* Block comment */
html {
content: "#{1}";
}

GraphQL

Bereichsformatierung für GraphQL hinzugefügt (#2319) von @josephfrazier

Wenn Sie versuchten, die Bereichsformatierung in einer GraphQL-Datei zu nutzen, wurde eine Exception geworfen. Jetzt funktioniert sie wieder korrekt und formatiert nur den ausgewählten Teil.

Dateiendung .gql für GraphQL-Parsing hinzugefügt (#2357) von @rrdelaney

Bei Facebook verwenden wir die Endung .graphql, aber es scheint auch üblich zu sein, .gql zu nutzen. Es kostet nicht viel, dies in der Heuristik zur Parser-Auswahl zu unterstützen.

CLI

Mehrere Muster mit Ignore-Mustern unterstützen (#2356) von @evilebottnawi

Es war bereits möglich, mehrere Glob-Muster zu verwenden, die additiv wirkten. Mit dieser Änderung können Sie ein Glob-Muster hinzufügen, um bestimmte Dateien zu ignorieren. Dies ist besonders nützlich, um tief verschachtelte Ordner zu ignorieren.

prettier --write '{**/*,*}.{js,jsx,json}' '!vendor/**'

--list-different mit --stdin kompatibel machen (#2393) von @josephfrazier

Dies ist eine praktische Methode, um festzustellen, ob Prettier ein Codestück anders formatieren würde. Die Konzepte waren bereits vorhanden, sie mussten nur korrekt verbunden werden.

$ echo 'call ( ) ;' | prettier --list-different
(stdin)
$ echo $?
1