Iconfont: generazione tramite Gulp.js

Aggiornamento del 25/06/2015: più modifiche dovute agli aggiornamenti di gulp-iconfont.

Bonjour à tous!
Questo è il mio primo articolo sul blog di UX-Republic e spiegherò come genero un iconfont dai file SVG rapidamente e nel modo più discreto possibile utilizzando Gulp.js.
iconfont Gulp.js

Perché?

Prima di utilizzare Gulp.js per generare un iconfont, ho esaminato il servizio App IcoMoon.
Funziona molto bene ma sono necessari molti passaggi prima che venga visualizzata un'icona sul tuo browser:

  • vai alla pagina,
  • importa gli SVG (sfoglia i suoi file sul tuo computer),
  • seleziona le sue icone,
  • fare clic su "Genera carattere",
  • clicca su “Scarica”,
  • decomprimere l'archivio,
  • spostare i file dei caratteri,
  • copia/incolla il CSS.

E se qualcosa è stato dimenticato o il file SVG non è corretto... devi ricominciare da capo.
Lo scopo di questo esercizio svolto con Gulp.js è di rendere automatica l'aggiunta di un'icona al suo iconfont. Che l'unica azione da fare è spostare il suo file SVG in una cartella ed eseguire un singolo comando nel terminale per avviare la generazione del nostro iconfont (font e CSS).

Prerequisiti

Prima di tutto dovrai installare alcuni strumenti sul tuo computer per poter generare il tuo iconfont.

Node.js

Logo NodeJSNode.js è una piattaforma software orientata alla rete. Consente l'uso di JavaScript altrove che in un browser web.
È necessario scaricare il programma di installazione ed eseguirlo come l'installazione di qualsiasi programma. Puoi già farlo seguendo il seguente link: https://nodejs.org/download/.

Gulp.js

Gulp J LogoGulp.js è un programma sviluppato come suggerisce il nome in JavaScript (estensione .js). È lui che ci permetterà di svolgere i nostri compiti.
Per installarlo il più facilmente possibile, lo faremo dalla riga di comando usando un terminale.

Configurazione del progetto

Iniziamo creando una cartella in cui inseriremo tutti i file e installeremo i moduli di cui avremo bisogno per generare il nostro iconfont.
Ecco la struttura che vi propongo:

iconfont_project
    \css
    \fonts
        \custom
    \icons
    \scss
        \templates
            _icons.scss
        _icons.scss
        fonts.scss
        main.scss
    gulpfile.js
    index.html

Apri un terminale e vai alla cartella del progetto.
Devi creare un file pacchetto.json che mirerà a raccogliere tutte le informazioni del progetto (nome, versione, moduli utilizzati, ecc.).
Per fare ciò, digita il seguente comando:

npm init

Installa Gulp.js

Per installare Gulp.js, digita il comando:

npm install --save-dev gulp

Installa i moduli Gulp.js

Abbiamo bisogno di diversi moduli per il nostro progetto:

Per installarli, digita questo comando:

npm install --save-dev gulp-sass gulp-iconfont gulp-consolidate lodash

Dovresti vedere apparire una nuova cartella denominata "node_modules", qui è dove sono installati Gulp.js e i suoi moduli.

Scrivi il Gulpfile

il file gulpfile.js è il file in cui scriveremo le nostre attività che verranno utilizzate per generare file di font e CSS.
Iniziamo chiamando le nostre librerie precedentemente scaricate:

var gulp = require('gulp')
  , sass = require('gulp-sass')
  , iconfont = require('gulp-iconfont')
  , consolidate = require('gulp-consolidate');

Scriviamo la nostra funzione iconfont (troverai il codice commentato su GitHub a fine articolo):

gulp.task('iconfont', function () {
  gulp.src('icons/**/*.svg')
    .pipe(iconfont({
      fontName: 'custom'
    , centerHorizontally: true
    , normalize: true
    , appendUnicode: true
    }))
    .on('glyphs', function (glyphs) {
      gulp.src('scss/templates/_icons.scss')
        .pipe(consolidate('lodash', {
          glyphs: glyphs
        , fontName: 'custom'
        , fontPath: '../fonts/custom/'
        , className: 'icon'
        }))
        .pipe(gulp.dest('scss'));
    })
    .pipe(gulp.dest('fonts/custom'));
});

Una seconda funzione chiamata “sass” per compilare il nostro CSS:

gulp.task('sass', function () {
  gulp.src('scss/**/*.scss')
    .pipe(sass({
      indentWidth: 4
    , outputStyle: 'expanded'
    }))
    .pipe(gulp.dest('css'));
});

Gulp.js richiede una funzione predefinita che dovrebbe essere denominata default:

gulp.task('default', ['sass'], function () {
  gulp.watch('scss/**/*.scss', ['sass']);
});

In questa funzione eseguiamo la funzione "sass", quindi diciamo a Gulp.js di controllare se uno dei nostri file Sass è stato modificato. In tal caso, eseguirà nuovamente la funzione "sass".

Creazione del modello

Il template è un file Sass in cui inseriremo le variabili delle informazioni che abbiamo scritto nel nostro file gulpfile.js, ovvero il nome del nostro font, il percorso dei nostri file di font, ecc.
Recupereremo anche la tabella in cui sono memorizzati i "punti di codice". Questo è il codice che verrà inserito nel contenuto CSS.
Nota: lo script prenderà il nome dell'SVG che gli hai assegnato.
Ecco un esempio di ciò che verrà generato in CSS se chiamo il mio file SVG "myicon.svg":

.icon-myicon:before {
    content: "\E001";
}

Scriveremo il nostro modello nella cartella scss/templates.
Iniziamo scrivendo il @font-face che chiamerà il nostro iconfont:

@font-face {
    font-family: '<%= fontName %>';
    font-weight: normal;
    font-style: normal;
    src: url('<%= fontPath %><%= fontName %>.eot');
    src: url('<%= fontPath %><%= fontName %>.woff2') format('woff2'),
         url('<%= fontPath %><%= fontName %>.woff') format('woff'),
         url('<%= fontPath %><%= fontName %>.ttf') format('truetype'),
         url('<%= fontPath %><%= fontName %>.eot?#iefix') format('embedded-opentype');
}

Tutto ciò che è contenuto in "<%=" e "%>" è in realtà codice JavaScript. "fontName" e "fontPath" sono variabili che prendono i parametri che abbiamo scritto nel metodo "consolidate" della nostra attività "iconfont" situata nel nostro gulpfile.js.
Quindi scriviamo la classe principale in cui chiameremo il font tramite font-family così come gli stili specifici dei font che inizializzeremo al valore predefinito per sovrascrivere gli stili che potrebbero essere applicati sui tag padre dove sarebbe la nostra icona :

.<%= className %>[class^="<%= className %>-"],
.<%= className %>[class*=" <%= className %>-"] {
    display: inline-block;
    font-family: '<%= fontName %>';
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    font-style: normal;
    font-variant: normal;
    font-weight: normal;
    line-height: 1;
    text-transform: none;
}

Le ultime due proprietà vengono utilizzate per attivare l'effetto ClearType per avere una resa migliore attivando l'antialiasing.
Creeremo quindi un loop per costruire una mappa che chiameremo "icone".
Una mappa è un tipo di dati in Sass che consente di strutturare i dati per coppia chiave/valore.

$icons: (
    <%= glyphs.map(function(glyph) {
        return glyph.name + ': '\' + '\\' + glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() + ''\'
    }).join(',\n ') %>
);

"glyphs" (variabile JavaScript, vedi file gulpfile.js) è un array contenente oggetti e per ognuno di essi eseguiremo una funzione che restituirà il nome del glifo (glyph.name) che è il nome del file SVG che tu diede. Questi nomi saranno le chiavi della mappa del Sass.
Per i valori della mappa restituiamo i punti di codice (glyph.codepoint) che convertiamo in esadecimale e che trasformiamo in maiuscolo.
Una volta generata la mappa, fornisce questo:

$icons: (
    antenna: '\E001',
    heart: '\E002'
);

E infine creiamo un loop (questa volta in Sass) che verrà utilizzato per leggere ogni elemento della nostra mappa e generare il CSS:

@each $name, $icon in $icons {
    .<%= className %>-#{$name}:before {
        content: $icon;
    }
}

In ogni ciclo, la prima variabile “nome” contiene le chiavi della mappa e la seconda “icona” contiene i valori.
Quindi scriviamo il CSS. In <%= className %> avremo il valore “icon” (assegnato nel file gulpfile.js).
#{$name} è la nostra chiave con il nome della classe.
$ icon è il nostro valore con il codice punto.
Perché #{$nome} e non solo $nome?
Scriviamo una variabile all'interno di una stringa di caratteri e utilizziamo qui ciò che chiamiamo ilinterpolazione.
Quando eseguiamo la nostra attività "iconfont", prenderà il file sass/templates/_icons.scss, eseguirà il codice JavaScript e genererà il file sass/_icons.scss. È il compito "sass" che genererà il CSS.

Esegui Gulp.js per generare l'icona

Per generare i file dei font e l'SCSS, dobbiamo eseguire la nostra attività "iconfont" in questo modo:

gulp iconfont

Per compilare il codice Sass in CSS, eseguiremo la nostra funzione "predefinita":

gulp default

Gulp.js ha semplificato le cose, possiamo omettere la parola "predefinito", eseguirà comunque il nostro compito per impostazione predefinita:

gulp

Usa la nostra nuova icona

Se prendiamo l'esempio sopra, per visualizzare la nostra icona dobbiamo scrivere un tag con la classe icon che è la classe principale e la classe icon-myicon che contiene il contenuto.
Esempio:

<i class="icon icon-myicon"></i>

Conclusione

Ci vuole un po' di tempo per impostare tutto, ma durante un progetto, l'aggiunta di un'icona al tuo font web viene eseguita in pochi secondi.
Tutti i file sono su GitHub di UX-Republic, potete scaricarli a questo indirizzo: https://github.com/ux-republic/gulp-icon-font.
Sentiti libero di porre le tue domande nei commenti.