Prettier 1.6: Konfigurationsfil, JSX
Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →
Den här versionen lägger till stöd för konfigurationsfiler i Prettier, samt viktiga förbättringar för JSX-utskrift.
En speciell tack till @azz som underhållit kodexemplet och implementerat många av ändringarna i den här versionen, då jag haft mindre tid för prettier på grund av semester och teambyte :)
Höjdpunkter
Konfiguration
Implementera cosmiconfig för arbetsytekonfiguration (#2434) av @azz
Sedan Prettiers allra första version har användare efterfrågat en .prettierrc-fil. Vi har strävat efter minimal konfiguration och att undvika att bli ytterligare en .dotfile man måste ha när ett nytt projekt startas.
Men sanningen är att vi behöver ett sätt att konfigurera Prettier som kan synkroniseras med alla integrationer. Genom att sakna en sådan, skötte vi problemet vidare till dem och såg flera inkompatibla lösningar. Nu hanteras det av Prettier självt.
// .prettierrc
{
"trailingComma": "es5",
"singleQuote": true
}
Mer information om konfigurationsfiler finns i README.
Stöd för .prettierignore-filer (#2412) av @evilebottnawi
Förutom att ange vilken konfiguration som ska användas, kan du skapa en .prettierignore-fil för att ange vilka filer som inte ska formateras.
## .prettierignore
dist/
package.json
JSX
Förbättra JSX-formatering (#2398) av @suchipi
Den sista stora användarhinder vid Prettier-adoption var hur JSX skrevs ut. Vi gick igenom alla rapporterade problem och gjorde flera ändringar:
- Arrow Function Expressions som returnerar JSX lägger nu till parenteser när JSX bryts över flera rader
// Before
const Component = props =>
<div>
Hello {props.name}!
</div>;
// After
const Component = props => (
<div>
Hello {props.name}!
</div>
);
- Villkorsuttryck inom (eller som innehåller) JSX formateras nu annorlunda med hjälp av parenteser
// 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 i logiska uttryck (|| eller &&) omges alltid med parenteser när JSX bryts
// Before
<div>
{props.isVisible &&
<BaseForm
url="/auth/google"
method="GET"
/>}
</div>;
// After
<div>
{props.isVisible && (
<BaseForm
url="/auth/google"
method="GET"
/>
)}
</div>
Förhoppningsvis stämmer detta bättre överens med hur communityn skriver JSX, så att Prettier kan användas på fler ställen ;)
Infoga enskilda uttryck inline i JSX (#2442) av @karl
Inledningsvis respekterade vi många radbrytningar från originalkoden i JSX. Detta minskade kodändringar men urholkade värdet av en konsekvent formatering, då samma kod kunde skrivas på två sätt.
Vid varje ny version har vi skärpt reglerna och bestämt hur kod alltid ska skrivas ut. Senast innebär det att enskilda barn i JSX-objekt nu alltid infogas inline.
// 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>;
Säkerställ radbrytning efter inledande JSX-mellanslag (#2348) av @karl
Inledande JSX-mellanslag placeras nu på egna rader. Det såg konstigt ut att ha dem före en tagg då de "indenterade" annorlunda jämfört med övrigt innehåll.
// 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>
Andra ändringar
JSON
Använd babylon.parseExpression för JSON (#2476) av @josephfrazier
Tidigare använde vi en strikt JSON-parser som kastade fel vid kommentarer eller avslutande kommatecken. Detta var opraktiskt eftersom många JSON-filer i praktiken tolkas med JavaScript eller json5 som är mindre strikta. Nu har vi lättat på detta och använder JavaScript-parsern för att tolka och formatera JSON. Det innebär att kommentarer kommer att bevaras om de fanns med.
Observera att detta är rent tilläggande – om din ursprungliga fil var JSON-kompatibel kommer den fortsätta att skriva ut giltig JSON.
// Before
Syntax error
// After
{ /* some comment */ "a": 1 }
JavaScript
Formattera 3 eller fler kedjade anrop på flera rader (#2673) av @azz
Detta var ett långvarigt problem med vårt sätt att formattera långa medlemskedjor. Prettier försökte klämma in allt utom den sista callbacken på en rad, vilket minskade läsbarheten. Lösningen vi kom fram till är att alltid bryta över flera rader när det finns tre eller fler funktionsanrop i en metodkedja.
// Before
Promise.resolve(0).catch(function(err) {}).then(function(res) {
//
});
// After
Promise.resolve(0)
.catch(function(err) {})
.then(function(res) {
//
});
Lägg till fler övervakande parenteser (#2423) av @azz
Parenteser är ett hett ämne eftersom de inte ingår i AST-trädet, så prettier ignorerar alla du lägger till och skapar dem från grunden. Vi gick igenom alla rapporterade fall och hittade några kantfall som blev förvirrande när jämförelser kedjades ihop och % blandades med * eller /.
En sak vi inte ändrar är att vi tar bort extra parenteser runt kombinationer av grundläggande aritmetiska operatorer: +-*/.
// Before
x !== y === z;
x * y % z;
// After
(x !== y) === z;
(x * y) % z;
Implementera prettier-ignore inuti JSX (#2487) av @azz
Det är användbart att kunna ignorera delar av JSX. Nu går det att lägga till en kommentar inuti ett JSX-uttryck för att ignorera formateringen av nästa element.
// Before
<Component>
{/*prettier-ignore*/}
<span ugly format="" />
</Component>
// Before
<Component>
{/*prettier-ignore*/}
<span ugly format='' />
</Component>
Svälj inte prettier-ignore-kommentarer (#2664)
För att hantera vissa kantfall har vi internt möjlighet att undvika att skriva ut kommentarer generellt och istället skriva dem vid anropsstället. Det visade sig att när vi använde prettier-ignore skrev vi inte ut kommentarerna alls! Detta är nu åtgärdat.
// Before
push(
<td> :)
</td>,
);
// After
push(
// prettier-ignore
<td> :)
</td>,
);
Fixa indrag för do-while-villkor (#2359) av @jsnajdr
Det tog 6 månader innan någon rapporterade att do-while-bryts när while-villkoret är flerradigt. Det bekräftar min misstanke att denna konstruktion inte används så mycket i praktiken.
// Before
do {} while (
someVeryLongFunc(
someVeryLongArgA,
someVeryLongArgB,
someVeryLongArgC
)
);
// After
do {} while (
someVeryLongFunc(
someVeryLongArgA,
someVeryLongArgB,
someVeryLongArgC
)
);
Bryt sekvensuttryck (#2388) av @bakkot
En annan underutnyttjad funktion i JavaScript är sekvensuttryck. Vi gjorde tidigare ett dåligt jobb med att formattera dem när de blev flerradiga – detta har nu korrigerats :)
// 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')
Trimma avslutande mellanslag från kommentarer (#2494) av @azz
Vi har med Prettier tagit ställning att ta bort alla avslutande mellanslag. Tidigare rörde vi inte kommentarer eftersom de är användargenererade, men det betyder inte att de ska ha mellanslag :)
// Before
// There is some space here ->______________
// After
// There is some space here ->
Fixa sammanflätade kommentarer i klassdekoratörer (#2660, #2661)
Vår hantering av kommentarer inuti klassdeklarationer var väldigt naiv – vi flyttade bara alla kommentarer till toppen. Nu är vi mer precisa och respekterar kommentarer som är sammanvävda inuti dekoratörer och runt extends.
// Before
// A
// B
// C
@Foo()
@Bar()
class Bar {}
// After
// A
@Foo()
// B
@Bar()
// C
class Bar {}
Förbättra formateringen av bind-uttryck (#2493) by @azz
Bind-uttryck diskuteras för närvarande i TC39 och vi insåg att vi kunde skriva ut dem med Prettier. Tidigare hanterade vi dem mycket naivt och kedjade bara ihop dem. Nu använder vi samma logik som för metodkedjor med .-operatorn. Vi har också fixat vissa hörnfall där det skulle generera ogiltig kod.
// 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);
Lägg till stöd för att skriva ut valfria catch-bindningar (#2570) by @existentialism
Det diskuteras i TC39 att göra argumentet för catch(e) valfritt. Låt oss se till att vi stöder detta i Prettier om utvecklare använder det.
// Before
Syntax error
// After
try {} catch {}
Lägg till stöd för att skriva ut valfri kedjesyntax (#2572) by @azz
Ett annat nytt förslag som diskuteras i TC39 är valfri kedjesyntax. Detta är för närvarande ett steg 1-förslag, så syntaxen kan komma att ändras.
obj?.prop // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call
Hantera Closure Compilers typomvandlingssyntax korrekt (#2484) by @yangsu
Kommentarer är knepiga att hantera rätt, speciellt när de har betydelse baserat på position. Vi hanterar nu specialfall för kommentarer som används som typomvandling i Closure Compiler så att de behåller samma semantik.
// Before
let assignment /** @type {string} */ = getValue();
// After
let assignment = /** @type {string} */ (getValue());
Inlinea första beräknade egenskapssökning i medlemskedja (#2670) by @azz
Det ser konstigt ut att ha en beräknad egenskapssökning på nästa rad, så vi lade till ett specialfall för att inlinea den.
// 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
Stöd för opaka typer och export star (#2543, #2542) by @existentialism
Flow-teamet introducerade två spännande funktioner med ny syntax. Vi stöder dem nu i Prettier. Jag har personligen väntat på opaka typer väääldigt länge!
// Before
Syntax error
// After
opaque type ID = string;
export type * from "module";
Ta bort onödiga citattecken i nycklar för typobjekt och gränssnitt (#2643) by @jackyho112
Vi har gjort detta för JavaScript-objekt sedan Prettiers tidiga dagar men glömde applicera samma sak på Flow- och TypeScript-typer.
// Before
type A = {
"string": "A";
}
// After
type A = {
string: "A";
}
Skriv ut TypeParameter även för unär funktionstyp (#2406) by @danwang
Hoppsan, vi strök generiken i detta specifika fall.
// Before
type myFunction = A => B;
// After
type myFunction = <T>(A) => B;
Behåll parenteser runt FunctionTypeAnnotation inuti ArrayTypeAnnotation (#2561) by @azz
Parenteser... en dag kommer vi fixa alla :)
// Before
const actionArray: () => void[] = [];
// After
const actionArray: (() => void)[] = [];
TypeScript
Stöd för TypeScript 2.5 RC (#2672) av @azz
TypeScript 2.5 RC släpptes nyligen, vilket tillåter dig att använda den kommande syntaxen för "valfria catch-bindningar" även i TypeScript. 🎉
Lägg inte till namespace-nyckelord till global deklaration (#2329) av @azz
// Before
namespace global {
export namespace JSX { }
}
// After
global {
export namespace JSX {}
}
Fixa <this.Component /> (#2472) av @backus
Tack vare JavaScripts otypade och tillåtande natur kunde vi slå ihop undefined med en sträng och få intressant kod som resultat. Nu fixat för detta fall :)
// Before
<undefined.Author />
// After
<this.Author />
Tillåt typassertioner att haka ihop (#2439) av @azz
Vi vill säkerställa att alla specialfall vi lagt till för JavaScript och Flow även fungerar för TypeScript-konstruktioner. I detta fall ska objekt också hakas ihop om de är omslutna av en as-operator.
// Before
const state = JSON.stringify(
{
next: window.location.href,
nonce,
} as State
);
// After
const state = JSON.stringify({
next: window.location.href,
nonce,
} as State);
Ta bort parenteser för typassertioner i binära uttryck (#2419) av @azz
Oftast lägger vi till parenteser för korrekthet, men i detta fall lade vi till dem i onödan. Nu kan vi ta bort dem för renare kod :)
// Before
(<x>a) || {};
// After
<x>a || {};
Skriv ut parenteser runt typassertion som vänsterled i tilldelning (#2525) av @azz
Ännu ett fall av saknade parenteser. Lyckligtvis får vi väldigt få sådana numera och de gäller extremt ovanliga edge cases.
// Before
foo.bar as Baz = [bar];
// After
(foo.bar as Baz) = [bar];
Skriv ut declare för TSInterfaceDeclaration (#2574) av @existentialism
Nyckelordet declare gör ingenting för interface så vi lade det aldrig dit. Men det kändes konstigt om du var i en deklarationsfil och såg allt ha declare före utom interfaces. Nu skriver vi ut declare om det fanns där från början.
// Before
interface Dictionary<T> {
[index: string]: T
}
// After
declare interface Dictionary<T> {
[index: string]: T
}
CSS
Normalisera citationstecken i CSS (#2624) av @lydell
För att få ut en första version av CSS-stödet behöll vi strängcitat som de var. Nu respekterar vi Prettiers singleQuote-alternativ. Svårigheten låg i att säkerställa korrekt kod för alla galna escape-sekvenser, unicode-tecken, emoji, specialregler som charset som bara fungerar med dubbla citat...
// Before
div {
content: "abc";
}
// After
div {
content: 'abc';
}
Normalisera nummer i CSS (#2627) av @lydell
Ytterligare ett område där vi kan återanvända logiken från JavaScript för att förbättra CSS-utskriften.
// Before
foo {
border: 1px solid rgba(0., 0.0, .0, .3);
}
// After
foo {
border: 1px solid rgba(0, 0, 0, 0.3);
}
Citera ociterade CSS-attributvärden i selektorer (#2644) av @lydell
Jag kan aldrig riktigt komma ihåg reglerna bakom citattecken runt attribut, så nu sätter vi alltid dit dem.
// Before
a[id=test] {}
// After
a[id="test"] {}
Lägg till stöd för css-nyckelord (#2337) av @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;
}
`;
Stöd för styled-components med befintlig komponent (#2552, #2619) av @azz
styled-components har många olika varianter för att märka malliteraler som CSS. Det är inte idealiskt att vi måste koda in alla dessa sätt i Prettier, men eftersom vi började kan vi lika gärna göra det ordentligt.
styled(ExistingComponent)`
css: property;
`;
styled.button.attr({})`
border: rebeccapurple;
`;
Trimma mellanslag i nedstigande kombinator (#2411) av @azz
CSS-tolkarna vi använder ger inte ett 100% semantiskt träd: i många fall ger de upp och returnerar bara det som matats in. Det är vårt ansvar att rensa upp detta samtidigt som vi bibehåller korrektheten. Här skrev vi tidigare ut mellanslag mellan selektorer som de var, men vi vet att det är korrekt att alltid ersätta dem med ett enda mellanslag.
// Before
.hello
.how-you-doin {
height: 42;
}
// After
.hello .how-you-doin {
height: 42;
}
Ta bort BOM före tolkning (#2373) av @azz
Jag har fortfarande mardrömmar från att hantera BOM i ett tidigare liv. Som tur är är det 2017 inte längre ett stort problem eftersom de flesta verktyg nu hanterar det. Tack @azz för att du fixade ett kantfall relaterat till CSS-tolkning.
// Before
[BOM]/* Block comment *
html {
content: "#{1}";
}
// After
[BOM]/* Block comment */
html {
content: "#{1}";
}
GraphQL
Lägg till stöd för intervallformatering av GraphQL (#2319) av @josephfrazier
Om du försökte använda intervallformateringsfunktionen i en GraphQL-fil kastade den tidigare ett fel, nu fungerar den korrekt och formaterar bara den del du valt.
Lägg till filändelsen .gql som ska tolkas som GraphQL (#2357) av @rrdelaney
På Facebook använder vi filändelsen .graphql, men det verkar vara vanligt med .gql också, och det kostar inte mycket att stödja det i heuristiken som avgör vilken tolk som ska användas.
CLI
Stöd för flera mönster med ignoreringsmönster (#2356) av @evilebottnawi
Det var redan möjligt att använda flera globmönster, men de var additiva. Med den här ändringen kan du lägga till ett globmönster för att ignorera vissa filer. Det kommer vara mycket praktiskt för att ignorera djupt nästlade mappar.
prettier --write '{**/*,*}.{js,jsx,json}' '!vendor/**'
Gör så att --list-different fungerar med --stdin (#2393) av @josephfrazier
Detta är ett praktiskt sätt att avgöra om Prettier skulle skriva ut en kodbit på ett annat sätt. Vi hade redan alla byggstenar på plats, vi behövde bara koppla ihop dem korrekt.
$ echo 'call ( ) ;' | prettier --list-different
(stdin)
$ echo $?
1
