Come sono sicuro che hai già raccolto bene a questo punto, ciò che rende PostCSS sorprendente è il suo fiorente ecosistema di plugin. E un'enorme ragione per cui ci sono così tanti ottimi plugin, con altri che escono sempre, è che PostCSS rende la creazione di un proprio plugin così accessibile per chiunque abbia qualche esperienza con JavaScript.
Non hai bisogno di permessi speciali per creare un plugin PostCSS; se vuoi farne uno, vai avanti e fallo. Attraverso questa libertà hai la possibilità di trasformare i tuoi processi di sviluppo CSS in qualsiasi cosa tu voglia che siano, senza menzionare l'opportunità di condividere il tuo lavoro con altri membri della comunità PostCSS in rapida crescita.
In questo tutorial imparerai come creare un plugin di base per PostCSS. Non entreremo troppo nell'API del plugin e non useremo alcuna codifica super hardcore. Io stesso sono uno sviluppatore front-end e le mie competenze JavaScript sono al livello che ti aspetteresti che fossero per una persona front-end, ma ciò non mi ha impedito di creare il mio primo plug-in PostCSS in poche ore.
Segui e scopri di persona quanto può essere accessibile lo sviluppo di plugin PostCSS!
Creeremo un plug-in che consente di inserire facilmente pile di font in famiglia di font
dichiarazioni tramite la seguente sintassi:
h1 font-family: "Open Sans", fontstack ("Arial");
Dopo la compilazione, il codice sopra si trasformerà in:
h1 font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
Anche se stai creando il tuo plugin, dovrai comunque iniziare creando un progetto Gulp o Grunt vuoto. Caricherete il vostro plug-in in questo progetto nello stesso modo in cui avete usato i plugin di altre persone in questa serie.
Puoi leggere come configurare i progetti Gulp o Grunt per PostCSS nelle esercitazioni precedenti:
Se non si desidera configurare manualmente il progetto da zero, è possibile scaricare i file sorgente allegati a questo tutorial ed estrarre il progetto di avviamento Gulp o Grunt in una cartella di progetto vuota. Quindi, con un terminale o un prompt dei comandi puntato sulla cartella, eseguire il comando installazione di npm
.
Crea una cartella in "node_modules" chiamata "postcss-myplugin". È comune usare il prefisso postcss-
per chiarire che il tuo plugin è per PostCSS.
Tutti i plugin PostCSS sono moduli di nodo, quindi sarà necessario trasformare la nuova cartella in una sola. Apri un terminale / prompt dei comandi, punta alla cartella appena creata ed esegui npm init
. Questo eseguirà l'impostazione di base di un modulo nodo, quindi segui semplicemente le istruzioni che appaiono nel tuo terminale, lasciando il campo "entry point" come predefinito "index.js".
Quando questo è fatto, con il terminale ancora puntato verso la cartella, esegui il comando npm install postcss --save
. Questo installerà PostCSS come una dipendenza per questo modulo, qualcosa che tutti i plugin PostCSS devono fare.
Creare un file denominato "index.js" nella cartella "postcss-myplugin". Aggiungi questo codice per caricare il modulo postcss principale:
var postcss = require ('postcss');
Poi sotto aggiungi questo wrapper di base che circonderà il codice di elaborazione del nostro plugin:
var postcss = require ('postcss'); module.exports = postcss.plugin ('myplugin', funzione myplugin (opzioni) funzione di ritorno (css) opzioni = opzioni || ; // codice di elaborazione verrà aggiunto qui);
Ora siamo pronti per caricare il tuo plug-in appena creato nel tuo progetto. Non farà nulla ancora, ma vogliamo solo ottenere la configurazione essenziale in atto.
Se stai usando Gulp, aggiungi questa variabile sotto quella già presente nel file:
var myplugin = require ('postcss-myplugin');
Ora aggiungi il nuovo nome della variabile nel tuo processori
array:
processori var = [myplugin];
Fai un rapido test per verificare che tutto funzioni eseguendo il comando gulp css
e controllando che un nuovo file "style.css" sia apparso nella cartella "dest" del tuo progetto.
Se stai usando Grunt, aggiorna il processori
oggetto, che è annidato sotto il opzioni
oggetto, al seguente:
processori: [require ('postcss-myplugin') ()]
Fai un rapido test per verificare che tutto funzioni eseguendo il comando grunt postcss
e controllando che un nuovo file "style.css" sia apparso nella cartella "dest" del tuo progetto.
Prima di iniziare ad aggiungere codice di elaborazione al nostro plug-in, aggiungeremo del codice di prova al nostro foglio di stile su cui il plugin può lavorare.
Al tuo file "src / style.css" aggiungi questo CSS:
h1 font-family: "Open Sans", fontstack ("Arial");
In questo momento, perché il nostro plugin non sta ancora facendo nulla, se compilate il vostro CSS vedrete esattamente lo stesso codice copiato direttamente nel file "style.css" della cartella "dest"..
Ora vogliamo iniziare la scansione del CSS del nostro file in modo che possiamo trovare qualsiasi istanza di fontstack ()
e elaborarli. Per iniziare, aggiungi il seguente codice dopo il opzioni = opzioni || ;
linea:
css.walkRules (function (rule) rule.walkDecls (function (decl, i) ););
L'uso di walkRules () nella prima riga consente di scorrere tutte le regole del tuo CSS; una regola è fondamentalmente il tuo selettore e gli stili che hai impostato tra le parentesi graffe. Nel nostro test CSS una regola sarebbe:
h1 font-family: "Open Sans", fontstack ("Arial");
Quindi, all'interno di ogni regola, walkDecls () scorre attraverso ogni dichiarazione; una dichiarazione è essenzialmente ogni riga nello stile. Nel precedente CSS, una dichiarazione sarebbe:
font-family: "Open Sans", fontstack ("Arial");
fontstack ()
Si usa la sintassiMentre ripetiamo ogni dichiarazione usando il codice che abbiamo appena aggiunto, la dichiarazione corrente è rappresentata da decl
, che ci consente di accedere sia alla proprietà della dichiarazione sia al suo valore tramite decl.prop
e decl.value
rispettivamente.
Con il nostro esempio CSS, decl.prop
ci darebbe famiglia di font
e decl.value
ci darebbe "Open Sans", fontstack ("Arial")
.
Vogliamo controllare tutti decl.value
nel nostro foglio di stile per vedere se contiene la stringa fontstack (
. Se lo fa, sappiamo che qualcuno sta cercando di utilizzare il nostro plugin per aggiungere uno stack di font al proprio CSS.
Dentro il walkDecl ()
loop, aggiungi:
var value = decl.value; if (value.indexOf ('fontstack (')! == -1) console.log ("found fontstack");
Per prima cosa stiamo prendendo decl.value
e memorizzandolo nella variabile valore
. Qualsiasi modifica a decl.value
sarà inviato nel foglio di stile compilato; stiamo memorizzando il suo contenuto nella variabile valore
quindi possiamo giocarci.
Quindi stiamo usando il metodo indexOf () per cercare il nostro nuovo valore
variabile per la stringa fontstack (
. Se viene trovato, stiamo registrando "found fontstack" sulla console in modo che possiamo controllare se tutto sta funzionando finora.
Correre gulp css
o grunt postcss
e dovresti vedere l'output "found fontstack" una volta nel tuo terminale / prompt dei comandi.
Ora che il nostro plugin è in grado di individuare istanze di fontstack ()
nel nostro foglio di stile, possiamo prepararci a convertire quell'istanza in uno stack di font, ad esempio un elenco di nomi di font. Ma prima di poterlo fare, dobbiamo prima definire questi stack di font.
Nella parte superiore del tuo file, sotto l'esistente postcss
variabile, crea una variabile chiamata fontstacks_config
. Trasformeremo questa variabile in un oggetto contenente coppie chiave-valore.
Per ogni voce nell'oggetto, la chiave dovrebbe essere il primo carattere nello stack di caratteri, ad es. 'Arial'
. Sarà la stringa passata da un utente a specificare lo stack di caratteri che desidera utilizzare, ad es. fontstack ( "Arial")
o fontstack ("Times New Roman")
.
Il valore in ogni coppia dovrebbe essere una stringa dell'elenco completo di caratteri contenuti nello stack di caratteri, ad es. 'Arial, "Helvetica Neue", Helvetica, sans-serif'
.
Aggiungi due voci al tuo fontstacks_config
oggetto, uno per 'Arial' e uno per 'Times New Roman', utilizzando gli stack di font forniti da CSS Font Stack.
Il tuo fontstacks_config
la variabile dovrebbe apparire così:
// Stack di font da http://www.cssfontstack.com/ var fontstacks_config = 'Arial': 'Arial,' Helvetica Neue ', Helvetica, sans-serif', 'Times New Roman': 'TimesNewRoman', Times New Roman ", Times, Baskerville, Georgia, serif '
La prima cosa che dobbiamo fare quando troviamo un'istanza di fontstack ()
essere usato è capire quale stack di font l'utente ha richiesto, cioè quale stringa hanno impostato tra le parentesi.
Ad esempio, se un utente è entrato fontstack ( "Arial")
vorremmo estrarre la stringa Arial
. Il motivo per cui vogliamo questa stringa è che ci darà una chiave che possiamo usare per cercare la pila di font corrispondente dalla nostra fontstacks_config
oggetto.
Aggiungi questo codice immediatamente dentro Se
dichiarazione che abbiamo aggiunto in precedenza, in sostituzione del console.log ("found fontstack");
linea:
// Ottieni il nome della stringa di caratteri richiesta facendo corrispondere la stringa all'interno delle parentesi di fontstack (). // Quindi sostituisci eventuali virgolette doppie o singole al suo interno. var fontstack_requested = value.match (/ \ (([^)] +) \) /) [1] .replace (/ ["'] / g," ");
Stiamo eseguendo due passaggi qui per estrarre il nome del fontstack come stringa.
Per prima cosa usiamo il metodo match () per trovare qualsiasi stringa tra parentesi nel nostro valore. Questo ci darebbe una stringa simile "Arial"
o 'Arial'
.
Vogliamo solo il nome del font, senza virgolette doppie o singole, quindi usiamo il metodo replace () per eliminarle dalla stringa, lasciandoci con una stringa non quotata come Arial
.
Questa stringa è memorizzata nel fontstack_requested
variabile.
Useremo il nostro nuovo creato fontstack_requested
variabile per cercare uno stack di font dal nostro fontstack_config
opzione. La parte difficile è che le chiavi in questo oggetto sono case sensitive, quindi se proviamo a cercare il Arial
entrata con la chiave arial
fallirà.
Per risolvere questo, andremo a "Title Case" la stringa, quindi per esempio tempi nuovi romani
sarebbe convertito a Times New Roman
. Lo faremo tramite una breve funzione personalizzata.
Sotto il tuo fontstacks_config
variabile aggiungi questo ToTitleCase ()
funzione:
// Credito per questa funzione a http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript/196991#196991 function toTitleCase (str) return str.replace (/ \ w \ S * / g, function (txt) return txt.charAt (0) .toUpperCase () + txt.substr (1) .toLowerCase (););
Ora applicheremo questa funzione al nostro fontstack_requested
variabile. Sotto la linea in cui hai creato il fontstack_requested
variabile, aggiungi questo codice:
// Titolo case le parole nel nome del font, nel caso in cui l'utente non lo facesse da solo fontstack_requested = toTitleCase (fontstack_requested);
Questo passa il fontstack_requested
variabile attraverso il nostro ToTitleCase ()
funzione, aggiornando il suo valore.
Ora abbiamo il nostro fonstack_requested
variabile impostata correttamente, possiamo usarla per cercare la pila di font corrispondente. Dopo la riga che hai appena aggiunto, inserisci questo codice:
// Cerca la fontstack richiesta nell'oggetto fontstack_config var fontstack = fontstacks_config [fontstack_requested];
Questo trova il valore nel fontstacks_config
oggetto che ha una chiave corrispondente alla stringa contenuta nel nostro fontstack_requested
variabile.
Ad esempio, se fontstack_requested
contiene la stringa Arial
, la voce in fontstacks_config
con la chiave Arial
sarà trovato e il valore 'Arial, "Helvetica Neue", Helvetica, sans-serif'
sarà restituito.
Questo valore restituito viene quindi memorizzato nella variabile fontstack
.
Ora abbiamo recuperato la nostra stringa di stack dei caratteri e pronta per essere inserita nel CSS, ma c'è ancora un'altra cosa che dobbiamo fare. Ricorderai nel nostro codice di test che abbiamo incluso il font "Open Sans" come font preferito, con lo stack di font che funge da fallback. Abbiamo anche bisogno di recuperare questo nome di carattere dal valore in modo che possa essere aggiunto al CSS che inseriamo nel foglio di stile elaborato.
Sotto il fontstack
riga variabile, aggiungi questo codice:
// Trova e memorizza qualsiasi nome di carattere che potrebbe essere già nel valore, prima della chiamata a fontstack () var first_font = value.substr (0, value.indexOf ('fontstack ('));
Questo codice utilizza il metodo substr () per trovare qualsiasi contenuto tra l'inizio del nostro valore
, (rappresentato da 0), e il nostro fontstack ()
istanza (che si trova usando il metodo indexOf ()). Qualunque contenuto sia trovato è memorizzato nella variabile first_font
.
Ad esempio, nel nostro codice di test valore
è uguale a "Open Sans", fontstack ("Arial")
, così la first_font
la variabile sarà impostata come "Apri Sans",
.
Ora abbiamo tutti i pezzi di cui abbiamo bisogno per creare un nuovo valore con cui sostituire il valore originale del nostro codice di prova "Open Sans", fontstack ("Arial")
.
Dopo l'ultimo codice che hai aggiunto, inserisci questo codice:
// Crea il nuovo valore per questa regola combinando le variabili first_font e fontstack var new_value = first_font + fontstack;
Qui stiamo unendo il nostro first_font
e fontstack
variabili in una singola stringa e memorizzarle nella variabile NEW_VALUE
.
Nel nostro codice di test, ciò significherebbe la combinazione "Apri Sans",
e Arial, "Helvetica Neue", Helvetica, sans-serif
.
Nostro NEW_VALUE
la variabile quindi manterrebbe la stringa "Open Sans", "Arial", Helvetica Neue ", Helvetica, sans-serif"
.
Questo ora ci dà il valore completo che vogliamo aggiungere al foglio di stile elaborato in modo che:
font-family: "Open Sans", fontstack ("Arial");
... si trasforma in:
font-family: "Open Sans", "Arial", Helvetica Neue ", Helvetica, sans-serif";
Ora che abbiamo il nostro nuovo valore pronto per essere inserito nel foglio di stile elaborato, tutto ciò che dobbiamo fare è aggiornare decl.value
. PostCSS si occuperà del resto, aggiungendo il nuovo valore nel CSS elaborato per noi.
Aggiungi questo codice dopo l'ultima riga che hai aggiunto:
// Reimposta il nuovo valore nel foglio di stile decl.value = new_value;
Questo set decl.value
per eguagliare il contenuto del nostro NEW_VALUE
variabile.
Il tuo plug-in è ora disponibile. Dagli un vortice compilando il tuo foglio di stile con gulp css
o grunt postcss
(con il terminale puntato verso la cartella del progetto, non la cartella dei plugin).
Il tuo file "dest / style.css" dovrebbe ora mostrare una pila di font completa:
h1 font-family: "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
Potresti voler consentire agli utenti del tuo plug-in di impostare le proprie opzioni, nello stesso modo in cui hai impostato le opzioni come hai usato i plugin PostCSS in questa serie.
Vogliamo che gli utenti siano in grado di impostare a fontstacks
opzione, aggiungendo stack di font aggiuntivi o ridefinendo stack di font esistenti, ad esempio:
fontstacks: 'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif', 'Arial': 'Arial, "Comic Sans"'
Nota: questo passaggio è facoltativo. Se lo desideri, puoi saltarlo e il tuo plugin funzionerà perfettamente, senza alcuna configurazione di set utente.
Abbiamo già la parte essenziale di abilitare le opzioni di set di utenti sul nostro plug-in. Nel nostro module.exports
linea noterai un opzioni
argomento è passato.
module.exports = postcss.plugin ('myplugin', function (options)
Riceveremo tutte le opzioni utente impostate dall'utente.
Vedrai anche che abbiamo la linea:
opzioni = opzioni || ;
Questo controlla se opzioni
ha qualsiasi valore e, in caso contrario, lo imposta su un oggetto vuoto. Questo ci assicura che non ci siano errori quando iniziamo a lavorare opzioni
ciò potrebbe derivare dall'essere indefinito.
Per iniziare, installeremo Underscore.js nel nostro progetto, poiché utilizzeremo il suo pratico metodo extend (). Esegui questo comando per installarlo nel plug-in che stai creando:
npm install underscore --save
Ora carica Underscore nel tuo plugin aggiungendo un _
variabile per richiederlo, sotto il tuo esistente postcss
variabile:
var postcss = require ('postcss'); var _ = require ('underscore');
Quindi quello che faremo è prendere il fontstacks_config
oggetto che abbiamo già creato all'interno del plugin e lo "estendiamo" con qualsiasi stack di font che l'utente ha impostato attraverso la configurazione delle opzioni.
Aggiungi questo codice direttamente sotto il opzioni = opzioni || ;
linea:
// Estende l'opzione predefinita fontstacks_config con qualsiasi set di caratteri personalizzati impostato nelle opzioni del plugin fontstacks_config = _.extend (fontstacks_config, options.fontstacks);
Il fontstacks
l'opzione che è stata impostata dall'utente è rappresentata da options.fontstacks
.
Usando Underscore estendere()
metodo, tutti i font stack in options.fontstacks
sono aggiunti a quelli già in fontstacks_config
. Ovunque ci sia una chiave corrispondente, il valore da options.fontstacks
sovrascriverà quello in fontstacks_config
. Ciò consente agli utenti di ridefinire qualsiasi stack di font esistente.
Nel tuo Gulpfile o Gruntfile, imposta a fontstacks
opzione e passa un nuovo stack di font e ridefinisce uno esistente:
/ * Gulpfile * / var processors = [myplugin (fontstacks: 'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif', 'Arial': 'Arial, "Comic Sans"' )]; / * Gruntfile * / processori: [require ('postcss-myplugin') (fontstacks: 'Extra Stack': '"Extra Stack", "Moar Fonts", Extra, serif', 'Arial': 'Arial,' Comic Sans"' ) ]
Ora aggiungi alcuni CSS aggiuntivi al tuo file "src / style.css" in modo da poter testare il nuovo stack di font che abbiamo appena aggiunto tramite le nostre opzioni:
h2 font-family: "Droid Sans", fontstack ("Extra Stack");
Ricompila il tuo CSS e dovresti vedere che il tuo stack di font "Arial" ora ha un output diverso e che lo stack di font "Extra Stack" è stato stampato correttamente:
h1 font-family: "Open Sans", Arial, "Comic Sans"; h2 font-family: "Droid Sans", "Extra Stack", "Moar Fonts", Extra, serif;
Questo è tutto! Hai finito. Hai completato il tuo primo plug-in PostCSS.
Ecco l'intera cosa su GitHub se dovessi aver bisogno di confrontare il tuo codice come riferimento.
Hai appena creato un intero plug-in PostCSS e spero che ti vengano in mente alcune idee sugli altri plug-in che ti piacerebbe creare. Forse c'è quella piccola cosa che ti infastidisce sempre quando scrivi CSS, e forse ora puoi trovare la tua soluzione per sbarazzartene definitivamente. O forse c'è qualcosa in più che pensi davvero che il CSS dovrebbe avere fuori dagli schemi, beh, ora puoi aggiungerlo da solo!
Per riassumere ciò che abbiamo coperto:
Come parte della versione 5.0 di PostCSS, Jed Mao ha contribuito con un gran numero di definizioni TypeScript che possono aiutare molto nello sviluppo di plugin attraverso il completamento automatico e la documentazione integrata durante la digitazione.
Se ti ritrovi nello sviluppo di plug-in PostCSS, questo è davvero qualcosa che vale la pena di integrare nel tuo flusso di lavoro. Io stesso non sono una mano di tipo Script, ma ho intenzione di inserire comunque il codice, quasi puramente per sfruttare questa funzionalità.
Se vuoi provare questo non è necessario essere su Windows o utilizzare Visual Studio, poiché puoi utilizzare il codice di Visual Studio open source gratuito, che gira su Windows, Mac e Linux ed è basato su Electron , la stessa shell che alimenta l'Editor di Atom.
Per un esempio su come incorporare queste definizioni TypeScript nel progetto, controlla il plugin postcss-font-pack. Forchetta e gioca in Visual Studio Code per vedere come funziona il completamento automatico e la documentazione in linea.
Grazie mille per aver seguito questa serie Deep Dive PostCSS. Spero che ti sia piaciuto leggerlo tanto quanto mi è piaciuto crearlo! Ancora più importante, spero che tu abbia una testa piena di idee su come puoi far funzionare PostCSS nella tua vita quotidiana di sviluppo web.
PostCSS è davvero un'incredibile nuova aggiunta al mondo del front-end, poiché il modo in cui facilita i plugin apre le porte a possibilità mai viste prima nello sviluppo di CSS. La gamma di plug-in disponibili al momento è già sufficiente per rimodellare completamente i flussi di lavoro giornalieri di una persona, e questo è solo ciò che è stato creato nello spazio di un paio d'anni.
Suggerirei che PostCSS non abbia ancora raggiunto il massimo, e che quando comincerà a essere qualcosa di cui la maggior parte degli sviluppatori CSS almeno conoscerà, se non lo giuro, vedremo che arriverà davvero al suo massimo. E con l'arrivo di altri sviluppatori front-end, vedremo più contributi all'ecosistema dei plugin, aggiungendo nuovi plugin e aiutandoci a creare quelli esistenti.
!