Som jeg er sikker på at du har blitt godt samlet på dette punktet, gjør PostCSS fantastisk, det er det blomstrende plugin-økosystemet. Og en stor grunn til at det er så mange flotte plugins, med flere som kommer ut hele tiden, er at PostCSS gjør at du lager din egen plugin så lett tilgjengelig for alle som har erfaring med JavaScript.
Du trenger ikke spesiell tillatelse til å lage et PostCSS-plugin; Hvis du vil lage en, går du bare rett og gjør det. Gjennom denne friheten har du evnen til å gjøre CSS utviklingsprosesser til alt du vil at de skal være, for ikke å nevne muligheten til å dele arbeidet ditt med andre medlemmer av det raskt voksende PostCSS-samfunnet.
I denne opplæringen lærer du hvordan du lager et eget eget plugin for PostCSS. Vi vil ikke gå for tungt inn i plugin-API, og vi vil ikke bruke noen super hardcore-koding. Jeg er selv en frontend-utvikler, og mine JavaScript-ferdigheter er på det nivået du forventer at de skal være for en front-end-person, men det stoppet ikke meg å lage mitt første PostCSS-plugin på bare noen få timer.
Følg med og se selv hvordan tilnærming til PostCSS-pluginutvikling kan være!
Vi lager et plugin som gjør det enkelt å sette inn skrifttypestabler i font-family
erklæringer via følgende syntaks:
h1 font-family: "Open Sans", fontstack ("Arial");
Etter samling vil ovennevnte kode bli til:
h1 font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
Selv om du lager din egen plugin, må du fortsatt starte med å lage et tomt Gulp eller Grunt-prosjekt. Du laster inn pluginet ditt i dette prosjektet på samme måte som du har brukt andre folks plugins i hele denne serien.
Du kan lese om hvordan du konfigurerer Gulp- eller Grunt-prosjekter for PostCSS i de tidligere opplæringene:
Hvis du ikke vil opprette prosjektet manuelt fra begynnelsen, kan du laste ned kildefilene som er vedlagt denne opplæringen, og trekke ut enten det forsynte Gulp eller Grunt-startprosjektet i en tom prosjektmappe. Deretter kjører kommandoen med en terminal eller kommandoprompt i mappen npm installasjon
.
Opprett en mappe i "node_modules" kalt "postcss-myplugin". Det er vanlig å bruke prefikset postcss-
for å gjøre det klart at plugin er for PostCSS.
Alle PostCSS-plugins er nodemoduler, så vi må slå den nye mappen til en. Åpne en terminal / kommandoprompt, pek på den nylig opprettede mappen, og kjør npm init
. Dette vil utføre det grunnleggende oppsettet til en nodemodul, så følg bare instruksjonene som kommer opp i terminalen din, og la "inngangspunkt" -feltet som standard "index.js".
Når dette er gjort, kjører du med terminalen din fremdeles i mappen. Kjør kommandoen npm installere postcss - save
. Dette vil installere PostCSS som en avhengighet for denne modulen, noe som alle PostCSS-plugins må gjøre.
Opprett en fil med navnet "index.js" i "postcss-myplugin" -mappen. Legg til denne koden for å laste inn hovedpostmodulen:
var postcss = krever ('postcss');
Deretter legger du til denne grunnleggende innpakningen som vil omgjøre prosesskoden vår:
var postcss = krever ('postcss'); module.exports = postcss.plugin ('myplugin', funksjon myplugin (alternativer) return function (css) options = options || ; // Behandlingskoden vil bli lagt til her);
Nå er vi klare til å laste det nyopprettede pluginet i prosjektet ditt. Det vil ikke gjøre noe enda, men vi vil bare få det nødvendige oppsettet på plass.
Hvis du bruker Gulp, legg til denne variabelen under den som allerede er i filen:
var myplugin = krever ('postcss-myplugin');
Legg nå det nye variabelenavnet i din prosessorer
matrise:
var prosessorer = [myplugin];
Gjør en rask test at alt fungerer ved å kjøre kommandoen gulp css
og sjekker at en ny "style.css" -fil har dukket opp i prosjektets "dest" -mappe.
Hvis du bruker Grunt, oppdaterer du prosessorer
objekt, som er nestet under opsjoner
objekt til følgende:
prosessorer: [krever ('postcss-myplugin') ()]
Gjør en rask test at alt fungerer ved å kjøre kommandoen grunt postcss
og sjekker at en ny "style.css" -fil har dukket opp i prosjektets "dest" -mappe.
Før vi begynner å legge til behandlingskode i pluginet, skal vi legge til noen testkode i vårt stilark som pluginet kan fungere på.
Til filen "src / style.css" legg til dette CSS:
h1 font-family: "Open Sans", fontstack ("Arial");
Akkurat nå, fordi vårt plugin ikke gjør noe enda, hvis du kompilerer CSS, ser du akkurat nøyaktig samme kode kopiert rett inn i "dest" -mappen sin "style.css" -fil.
Nå vil vi begynne å skanne CSS av filen, slik at vi kan finne noen forekomster av fontstack ()
og behandle dem. For å komme i gang på dette, legg til følgende kode etter alternativer = alternativer || ;
linje:
css.walkRules (funksjon (regel) rule.walkDecls (funksjon (decl, i) ););
Ved å bruke walkRules () i den første linjen iterates gjennom hver regel i CSS; en regel er i utgangspunktet din selector og stilene du har satt mellom sine krøllete braces. I vår test CSS vil en regel være:
h1 font-family: "Open Sans", fontstack ("Arial");
Deretter, i hver regel, går walkDecls () gjennom hver deklarasjon; en erklæring er i hovedsak hver linje i stilen. I ovennevnte CSS vil en erklæring være:
font-family: "Open Sans", fontstack ("Arial");
fontstack ()
Syntaks er bruktNår vi gjentar gjennom hver deklarasjon ved hjelp av koden vi nettopp har lagt til, er gjeldende deklarasjon representert av decl
, som gir oss tilgang til både deklarasjonens eiendom og dens verdi via decl.prop
og decl.value
henholdsvis.
Med vårt eksempel CSS, decl.prop
ville gi oss font-family
og decl.value
ville gi oss "Open Sans", fontstack ("Arial")
.
Vi vil sjekke hver decl.value
i stilarket vårt for å se om det inneholder strengen fontstack (
. Hvis det gjør, vet vi at noen prøver å bruke pluginet vårt for å legge til en fontstabel til deres CSS.
Inne i walkDecl ()
sløyfe, legg til:
var verdi = decl.value; hvis (value.indexOf ('fontstack (')! == -1) console.log ("found fontstack");
Først tar vi decl.value
og lagre den i variabelen verdi
. Eventuelle endringer i decl.value
vil bli sendt inn i det sammensatte stilarket; Vi lagrer innholdet i variabelen verdi
slik at vi kan rote rundt med det.
Så bruker vi indeksen indexOf () for å søke i vårt nye verdi
variabel for strengen fontstack (
. Hvis den er funnet, logger vi "funnet fontstack" til konsollen, så vi kan sjekke om alt jobber så langt.
Løpe gulp css
eller grunt postcss
og du bør se "funnet fontstack" -utgang en gang i terminal / kommandoprompt.
Nå som vår plugin er i stand til å finne forekomster av fontstack ()
I vårt stilark kan vi gjøre oss klar til å konvertere den forekomsten til en fontstabel, det vil si en liste over skriftnavn. Men før vi kan gjøre det, må vi først definere disse skriftstablene.
Øverst på filen din, under eksisterende postcss
variabel, opprett en variabel som heter fontstacks_config
. Vi skal omdanne denne variabelen til et objekt som inneholder nøkkelverdier.
For hver oppføring i objektet, bør nøkkelen være den første skrifttypen i fontstakken, f.eks. 'Arial'
. Det blir strengen en bruker passerer for å spesifisere skrifttypestakken de vil bruke, f.eks. fontstack ( "Arial")
eller fontstack ("Times New Roman")
.
Verdien i hvert par skal være en streng av den fulle listen over skrifttyper som finnes i fontstakken, f.eks. 'Arial,' Helvetica Neue ', Helvetica, sans-serif'
.
Legg til to oppføringer til din fontstacks_config
objekt, en for 'Arial' og en for 'Times New Roman', ved hjelp av skriftstablene som tilbys av CSS Font Stack.
Din fontstacks_config
variabel skal se slik ut:
// Font stabler fra http://www.cssfontstack.com/ var fontstacks_config = 'Arial': 'Arial,' Helvetica Neue ', Helvetica, sans-serif', 'Times New Roman': 'TimesNewRoman, Times Times Roman ", Times, Baskerville, Georgia, serif '
Det første vi må gjøre når vi finner en forekomst av fontstack ()
blir brukt til å finne ut hvilken skrifttypestabel brukeren har bedt om, dvs. hvilken streng de har satt mellom parentesene.
For eksempel, hvis en bruker angitt fontstack ( "Arial")
vi ønsker å trekke ut strengen arial
. Grunnen til at vi vil ha denne strengen er at den vil gi oss en nøkkel vi kan bruke til å slå opp den tilsvarende skriftstakken fra vår fontstacks_config
gjenstand.
Legg til denne koden umiddelbart inne i hvis
uttalelse vi la til tidligere, erstatte console.log ("funnet fontstack");
linje:
// Få navnet på fontstacken som er forespurt, ved å matche strengen inne i parentesen til fontstack (). // Deretter erstattes eventuelle doble eller enkle sitater deri. var fontstack_requested = value.match (/ \ (([^)] +) \) /) [1] .replace (/ ["'] / g," ");
Vi utfører to trinn her for å trekke ut skrifttypens navn som en streng.
Først bruker vi metoden match () for å finne hvilken streng som er mellom parentesene i vår verdi. Dette ville gi oss en streng som "Arial"
eller 'Arial'
.
Vi vil bare ha skrifttypenavnet, uten noen dobbelte eller enkle anførselstegn, så bruker vi erstatningen () -metoden for å fjerne dem fra strengen, og gir oss en unotert streng som arial
.
Denne strengen er lagret i fontstack_requested
variabel.
Vi skal bruke vår nyopprettede fontstack_requested
variabel for å se opp en fontstabel fra vår fontstack_config
alternativ. Den vanskelige delen er nøklene i dette objektet er saksfølsomme, så hvis vi prøver å slå opp arial
inngang med nøkkelen arial
det vil mislykkes.
For å løse dette, skal vi "Tittel Case" strengen, så for eksempel Times New Roman
ville bli konvertert til Times New Roman
. Vi gjør dette via en kort tilpasset funksjon.
Under din fontstacks_config
variabel legg til dette toTitleCase ()
funksjon:
// Kreditt for denne funksjonen til http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript/196991#196991 funksjonen tilTitleCase (str) return str.replace (/ \ w \ S * / g, funksjon (txt) return txt.charAt (0) .toUpperCase () + txt.substr (1) .toLowerCase (););
Nå skal vi bruke denne funksjonen til vår fontstack_requested
variabel. Under linjen der du opprettet fontstack_requested
variabel, legg til denne koden:
// Tittel faller ordene i skrifttypenavnet, bare hvis brukeren ikke gjorde det selv fontstack_requested = toTitleCase (fontstack_requested);
Dette går forbi fontstack_requested
variabel gjennom vår toTitleCase ()
funksjon, oppdatering av verdien.
Nå har vi vår fonstack_requested
variabel satt riktig, kan vi bruke den til å slå opp den tilsvarende skrifttypestakken. Etter linjen du nettopp har lagt til, sett inn denne koden:
// Søk etter den ønskede fontstakken i fontstack_config objektet var fontstack = fontstacks_config [fontstack_requested];
Dette finner verdien i fontstacks_config
objekt som har en nøkkel som samsvarer med strengen som finnes i vår fontstack_requested
variabel.
For eksempel, hvis fontstack_requested
inneholder strengen arial
, oppføringen i fontstacks_config
med nøkkelen arial
vil bli funnet og verdien 'Arial,' Helvetica Neue ', Helvetica, sans-serif'
vil bli returnert.
Denne returnerte verdien lagres deretter i variabelen fontstack
.
Nå har vi vår skriftstabelstreng hentet og klar til å bli satt inn i CSS, men det er fortsatt en ting vi må gjøre. Du vil huske i vår testkode vi inkluderte skrifttypen "Open Sans" som den foretrukne skrifttypen, med skrifttypestakken som fungerer som en tilbakebetaling. Vi må også hente dette skriftnavnet fra verdien slik at den kan legges til CSS vi legger inn i det behandlede stilarket.
Under fontstack
variabel linje, legg til denne koden:
// Finn og lagre eventuelle skrifttypenavn som allerede kan være i verdien, før fontstacken () samtale var first_font = value.substr (0, value.indexOf ('fontstack ('));
Denne koden bruker metoden substr () for å finne noe innhold mellom begynnelsen av vår verdi
, (representert av 0), og vår fontstack ()
forekomst (lokalisert ved hjelp av indexOf () -metoden). Uansett innhold er funnet, lagres i variabelen first_font
.
For eksempel, i vår testkode verdi
er lik "Open Sans", fontstack ("Arial")
, så first_font
variabel vil bli satt som "Open Sans",
.
Vi har nå alle brikkene vi trenger for å skape en ny verdi som erstatter vår testkode sin opprinnelige verdi av "Open Sans", fontstack ("Arial")
.
Etter den siste koden du la til, legg inn denne koden:
// Opprett den nye verdien for denne regelen ved å kombinere first_font og fontstack-variablene var new_value = first_font + fontstack;
Her kombinerer vi vår first_font
og fontstack
variabler i en enkelt streng og lagrer den i variabelen new_value
.
I vår testkode vil dette bety å kombinere "Open Sans",
og Arial, "Helvetica Neue", Helvetica, sans-serif
.
Våre new_value
variabel vil da holde strengen "Open Sans", "Arial," Helvetica Neue ", Helvetica, sans-serif '
.
Dette gir oss nå den fullstendige verdien som vi ønsker å legge til i det behandlede stilarket slik at:
font-family: "Open Sans", fontstack ("Arial");
... forvandles til:
font-familie: "Open Sans", "Arial," Helvetica Neue ", Helvetica, sans-serif ';
Nå som vi har vår nye verdi klar til å bli satt inn i det behandlede stilarket, er alt vi trenger å oppdatere decl.value
. PostCSS vil ta vare på resten, legge til den nye verdien i den behandlede CSS for oss.
Legg til denne koden etter siste linje du la til:
// Send den nye verdien tilbake til stilarket decl.value = new_value;
Dette setter decl.value
å likne innholdet i vår new_value
variabel.
Pluggen din er nå god å gå. Gi det en virvel ved å kompilere stilarket med gulp css
eller grunt postcss
(med din terminal peket på prosjektmappen din, ikke din plugin-mappe).
Din "dest / style.css" -fil skal nå vise en fullstendig skriftstabel:
h1 font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
Du vil kanskje tillate brukere av pluginet ditt å angi egne alternativer, på samme måte som du har satt inn alternativer som du har brukt PostCSS-plugins gjennom hele denne serien.
Vi vil at brukerne skal kunne sette en fontstacks
alternativ, enten du legger til ekstra skriftstabler eller omdefinerer eksisterende skriftstabler, for eksempel:
fontstacks: 'Extra Stack': '"Extra Stack", "Moar Fonts", Ekstra, serif', 'Arial': 'Arial, Comic Sans' '
Merk: dette trinnet er valgfritt. Hvis du ønsker det, kan du hoppe over det, og pluginet ditt vil fungere perfekt, bare uten noen konfigurasjon av brukeren.
Vi har allerede den mest avgjørende delen av å gjøre det mulig for brukerinnstillingene på plass i plugin-modulen. I vår module.exports
linje vil du legge merke til en opsjoner
argumentet blir vedtatt.
module.exports = postcss.plugin ('myplugin', funksjon (alternativer)
Vi mottar alle brukeralternativer en bruker angir gjennom dette.
Du ser også at vi har linjen:
alternativer = alternativer || ;
Dette sjekker for å se om opsjoner
har noen verdi, og hvis den ikke gjør det, setter den til en tom gjenstand. Dette sørger for at vi ikke får noen feil når vi begynner å jobbe med opsjoner
Det kan komme fra at det er udefinert.
For å komme i gang, skal vi installere Underscore.js inn i vårt prosjekt, da vi bruker den praktiske extend () -metoden. Kjør denne kommandoen for å installere den i plugin du bygger:
npm installere understreking - lagre
Legg nå Underscore i plugin ved å legge til en _
variabel for å kreve det, under din eksisterende postcss
variabel:
var postcss = krever ('postcss'); var _ = krever ('understreking');
Neste hva vi skal gjøre er å ta fontstacks_config
objekt vi allerede opprettet i pluginet, og "forlenge" det med eventuelle fontstabler som brukeren har angitt gjennom opsjonskonfigurasjonen.
Legg til denne koden direkte under alternativer = alternativer || ;
linje:
// Utvid standard fontstacks_config-alternativet med noen egendefinerte fontstabler som er angitt i alternativene for plugin fontstacks_config = _.extend (fontstacks_config, options.fontstacks);
De fontstacks
alternativet som er angitt av brukeren er representert av options.fontstacks
.
Ved å bruke Underscore's forlenge()
metode, alle font stablene i options.fontstacks
legges til de som allerede er i fontstacks_config
. Uansett hvor det er en matchende nøkkel, er verdien fra options.fontstacks
vil overskrive den i fontstacks_config
. Dette lar brukerne omdefinere eksisterende skriftstabler.
I din Gulpfile eller Gruntfile, sett a fontstacks
alternativ og send en ny skriftstapel samt omdefinere en eksisterende:
/ * Gulpfile * / var prosessorer = [myplugin (fontstacks: 'Extra Stack': '"Extra Stack", "Moar Fonts", Ekstra, serif', 'Arial': 'Arial, Comic Sans' ' )]; / * Gruntfile * / prosessorer: [krever ('postcss-myplugin') (fontstacks: 'Extra Stack': '"Ekstra Stack", "Moar Fonts", Ekstra, serif', 'Arial': 'Arial' Comic Sans "')]
Legg nå litt ekstra CSS i filen "src / style.css", så vi kan teste den nye skrifttypestakken vi nettopp har lagt til via våre alternativer:
h2 font-family: "Droid Sans", fontstack ("Extra Stack");
Kompilér CSS-en din, og du bør se at din Arial-fontstapel nå har forskjellig utgang, og at fontstapelen for ekstra stack har riktig utskrift:
h1 font-family: "Open Sans", Arial, "Comic Sans"; h2 font-family: "Droid Sans", "Extra Stack", "Moar Fonts", Ekstra, serif;
Det er det! Du er ferdig. Du har fullført ditt første PostCSS-plugin.
Her er hele greia på GitHub, må du sammenligne koden til den som referanse.
Du har nettopp opprettet et helt PostCSS-plugin, og jeg håper noen ideer kommer til å tenke på andre plugins du vil gjerne gjøre. Kanskje det er en liten ting som alltid har bugget deg når du skriver CSS, og kanskje nå kan du komme med din egen løsning for å bli kvitt det for godt. Eller kanskje det er noe ekstra du tror CSS burde ha ut av boksen - vel, nå kan du legge det inn for deg selv!
For å oppsummere hva vi har dekket:
Som en del av 5.0-utgivelsen av PostCSS, har Jed Mao bidratt med et flott sett med TypeScript-definisjoner som kan hjelpe mye med plugin-utvikling gjennom å gi autofullføring og inline-dokumentasjon mens du skriver.
Hvis du finner deg selv i PostCSS-pluginutvikling, er dette virkelig noe verdt å se på å inkorporere i arbeidsflyten din. Jeg er selv ikke en dab TypeScript-hånd, men kommer til å hoppe inn i kodingen med det uansett, nesten rent slik at jeg kan utnytte denne funksjonaliteten.
Hvis du vil prøve dette ut, trenger du ikke å være på Windows eller ved hjelp av Visual Studio, da du kan bruke den gratis, åpen kildekode Visual Studio-koden, som kjører på Windows, Mac og Linux, og er bygget på Electron , det samme skallet som driver Atom Editor.
For et eksempel på hvordan du innlemmer disse TypeScript-definisjonene i prosjektet, sjekk ut plugin-font-pack-plugin. Fork det og ha et spill i Visual Studio Code for å se hvordan autocompletion og inline dokumentasjon fungerer.
Tusen takk for at du følger med denne PostCSS Deep Dive-serien. Jeg håper du likte å lese det så mye som jeg likte å skape det! Enda viktigere, jeg håper du har et hode fullt av ideer om hvordan du kan sette PostCSS på jobb i ditt daglige webutviklingsliv.
PostCSS er virkelig et utrolig nytt tillegg til front-end-verdenen, slik måten det letter plugins åpner dører for muligheter vi aldri har hatt før i CSS-utvikling. Utvalget av plugins som er tilgjengelig akkurat nå, er allerede nok til å omforme en persons daglige arbeidsflyter helt, og det er bare med det som er opprettet i løpet av et par år.
Jeg vil foreslå at PostCSS har ennå ikke topp, og som det begynner å være noe de fleste CSS utviklere i det minste vet om, om ikke sverger ved, ser vi det virkelig kommer inn i sin skritt. Og med flere fremtidsutviklere som kommer ombord, ser vi flere bidrag til plugin-økosystemet, legger til nye plugins og bidrar til å bygge opp eksisterende.
!