
Come migliorare lo sviluppo frontend con Gulp
Ad un certo punto del proprio percorso di crescita come frontend developer cominci a farti domande che non riguardano più il giusto font da usare o la giusta palette colori, ma cominci a domandarti se ciò che stai sviluppando con tanto amore è performante. Nella stragrande maggioranza dei casi, no.
Le motivazioni possono essere diverse, come ad esempio delle immagini non ottimizzate, il server configurato male o non adatto alle proprie esigenze oppure codice scritto male o superfluo per la pagina in uso.
Ho parlato in un articolo precedente del Critical CSS, ma forse è il caso di fare un passo indietro e spiegare per bene come Gulp possa ottimizzare un pochino il codice che scrivi. Attenzione! Un codice rindondante e scritto da cani, rimane un codice rindonante e scritto da cani. Gulp permette di ottimizzare dove possibile, ma cerchiamo di capire meglio di cosa sto parlando
Cos’è Gulp?
Gulp è un toolkit JavaScript che ti aiuta ad implementare delle task, utili ad automatizzare e semplificare il tuo workflow. Se usato correttamente può risolvere parecchie rotture di scatole in maniera del tutto automatica.
In questo articolo vedremo come implementare delle task di base, ma in futuro potrai sempre decidere di estenderle in base alle tue esigenze.
Installare Gulp
Prima di iniziare a scrivere codice, dobbiamo installare la dipendenza principale di Gulp, Node.js.
Se non hai Node installato sul tuo computer, puoi scaricarlo dal sito ufficiale.
Una volta installato Node, puoi installare Gulp usando la seguente istruzione da riga di comando (Terminale su Mac/Linux o Powershell su Windows).
// per utenti Windows
npm install gulp -g
// per utenti Mac/Linux
sudo npm install gulp -g
Nota: Gli utenti Mac e Linux devono anteporre la parola chiave sudo per eseguire il comando come amministratori.
La sintassi usata specifica di installare Gulp nel proprio computer usando npm (Node Package Manager).
La flag -g specifica che npm installerà Gulp globalmente nel sistema, questo ti permetterà di eseguire i comandi gulp ovunque nel tuo computer.
Ora che Gulp è installato possiamo creare un progetto per poterne vedere le potenzialità.
Creare un progetto
Sul tuo desktop crea una cartella con nome a piacere, la quale conterrà tutto il progetto. Apri la cartella nel prompt dei comandi (trascinala nel terminale) ed esegui il seguente comando
// Inizializza il progetto
npm init
Il comando qui sopra creerà un file chiamato package.json, il quale conterrà tutte le informazioni sul progetto, come le dipendenze, script da eseguire, ecc.
npm init
ti mostrerà quanto segue:

Dopo la creazione del package.json, installiamo gulp a livello di progetto usando il seguente comando
npm install gulp --save-dev
Questo installerà gulp come una dipendenza di sviluppo del progetto invece che globalmente.
La flag --save-dev
installerà e inserirà il nome del pacchetto sotto le dev dependency nel file package.json.
Quando l’esecuzione del comando sarà portata a termine nella tua cartella potrai notare una cartella node_modules, essa contiene le varie dipendenze e tende a diventare molto pensante.
Piccolo consiglio: se devi trasferire il tuo progetto a qualcuno non copiare la cartella node_modules, colui a cui la passerai dovrà semplicemente eseguire il comando npm init
affinché npm legga il package.json e scarichi in automatico tutte le dipendeze del progetto. Stesso discorso vale se trasferisci il tuo progetto su Github o simili, escludi la cartella node_modules attraverso il file .gitignore.
Perfetto! Ora sei pronto, ma prima di proseguire oltre dobbiamo parlare un attimo di Gesù Cristo nostro signore come strutturare il nostro progetto.
Come strutturare la cartella del progetto
Gulp è abbastanza flessibile da lavorare con qualsiasi struttura, ma questo non vuol dire mettere tutti i file nella root directory. Per questo progetto useremo la seguente struttura.

In questa struttura, useremo la cartella src per lo svilippo, mentre dist (diminutivo di “Distribuzione”) conterrà i file ottimizzati per il sito di produzione.
La struttura del progetto dobbiamo tenerla a mente quando lavoriamo con Gulp. Il passaggio successivo è la creazione del file gulpfile.js (già presente nel mio screenshot), il quale conterrà tutte le task di Gulp.
Creare la prima Gulp Task
Come prima cosa dobbiamo richiamare gulp nel nostro file gulpfile.js
const gulp = require('gulp');
Giusto per capire la struttura di una task di Gulp, creiamone una inutile e chiamala “hello from gulp”.
gulp.task('hello', function (done) {
console.log('Hello from Gulp');
done();
});
La riga di comando mostrerà l’output Hello from Gulp quando il comando gulp hello verrà eseguito.

Ovviamente, le task Gulp sono molto più complesse di così, contengono metodi addizionali e plugin.
Una vera task Gulp assomiglia di più a questo:
gulp.task('nome-task', function() {
return gulp
.src('file-sorgente') // Recupera file sorgente
.pipe(unPluginGulp()) // Processalo con un plugin Gulp
.pipe(gulp.dest('destinazione')); // Salvalo nella cartella di destinazione
});
gulp.src comunica alla task di Gulp quali file usare, mentre gulp.dest comunica dove salvare l’output dopo che la task termina la sua esecuzione.
Preprocessare con Gulp
In Gulp possiamo compilare file Sass in CSS con l’ausilio del plugin gulp-sass. Prima di tutto, installiamo il plugin come dipendenza di sviluppo usando il seguente comando:
npm install gulp-sass --save-dev
Dobbiamo richiamare il plugin all’interno del nostro gulpfile.js
const sass = require('gulp-sass');
Ora che il plugin è disponibile, possiamo creare una task che compili il file scss.
gulp.task('sass', function() {
return gulp
.src('src/scss/main.scss')
.pipe(sass())
.pipe(gulp.dest('src/css'));
});
La task, come menzionato poc’anzi, recupererà il file main.scss dalla cartella scss in src, eseguirà il plugin gulp-sass e salverà il risultato della task nella cartella css in src.
Per verificare che la task funzioni correttamente creiamo il file main.scss e aggiungiamo un paio di righe.
$primary-color: #bada55;
$font: 'Arial';
body {
background: $primary-color;
font-family: $font;
p {
color: #ffffff;
}
}
Se da riga di comando esegui gulp sass
, vedrai che automaticamente verrà creato il file main.css in src/css. Inoltre, se apri il file appena creato, vedrai che non sarà più in SCSS, ma in CSS.
body {
background: #bada55;
font-family: "Arial"; }
body p {
color: #ffffff; }
Meraviglioso, ora puoi compilare i file SASS in file CSS.
Sicuramente in futuro vorrai compilare più file SCSS, una delle peculiarità del linguaggio è proprio la facilità con la quale puoi frammentarlo in piccolo pezzi, semplificandone la manutenzione.
Per poter processare più file useremo i Node Globs.
Usare i Node Globs per processare file multipli
I Globs sono usati per confrontare i patterns.
Ci sono 4 globs differenti:
*.scss
: l’asterisco è una wildcard che confronta ogni file che termina con l’estensione .scss nella directory.**/*.scss
: in questa versione l’asterisco confronta ogni file che termina con .scss nella cartella principale e in ogni cartella figlia.!not.scss
: il punto esclamativo indica a gulp di escludere i file scss.*.+(scss|sass)
: il più e le parentesi permettono di creare pattern multipli, ogni pattern è separato da una pipe (la barra verticale).
Ora che conosci i globs, puoi procedere alla sostituzione di src/scss/main.scss con qualcosa di più “generico”, magari un pattern che controlli la root directory e ogni cartella figlia. Indovinato? Sì, è proprio src/scss/**/*.scss.
gulp.task('sass', function() {
return gulp
.src('src/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('src/css'));
});
Da questo momento potrai scrivere file SCSS multipli e compilarli con il comando gulp sass
da terminale.
Aspettare che un file SASS cambi
Giunti a questo punto forse ti starai probabilmente chiedendo, ma devo eseguire ogni volta il comando gulp sass? Se così fosse, sarebbe una palla eseguirlo ogni sacrosanta volta.
Fortunatamente Gulp viene in nostro soccorso con il metodo watch, il quale controlla se vengono effettuate delle modifiche ai file desiderati ed esegue una task.
Per controllare eventuali modifiche ai file SCSS scriveremo nel gulpfile.js
gulp.watch('src/scss/**/*.scss', gulp.series('sass'));
Magari piuttosto che lasciare un comando così “volante” nel file è meglio creare una task
gulp.task('watch', function() {
gulp.watch('src/scss/**/*.scss', gulp.series('sass'));
});
Ora se esegui gulp watch nella riga di comando la task resterà in esecuzione, in attesa che un file scss venga salvato per eseguire automaticamente la task sass.
In pratica abbiamo automatizzato, l’automazione.
CSS Vendor Free
Ancora oggi vengono usati quei dannatissimi vendor prefix (-moz-, -ms-, -o-, -webkit-), senza quelli alcuni browser non riconoscono la proprietà CSS, ignorandola. Un vero rompimento di palle.
Fortunatamente Gulp viene ancora una volta in nostro soccorso con il plugin gulp-prefixer. Esso ci permetterà di aggiungere automaticamente i prefissi, evitando una montagna di bestemmie durante lo sviluppo.
Installa il plugin con il seguente comando:
npm install gulp-autoprefixer --save-dev
Quindi modifichiamo la task sass per aggiungere i prefissi automaticamente
const autoprefixer = require('gulp-autoprefixer');
gulp.task('sass', function() {
return gulp
.src('src/scss/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest('src/css'));
});
Ora, eseguendo la task gulp sass il file scss verrà compilato in css con i prefissi, ove necessario.
Live-reload usando la sincronizzazione del browser
Save, Refresh, Repeat. Se scrivi CSS da un po’, sicuramente conosci la rottura di salvare, aggiornare la pagina, vedere che tutto è un bordello e tornare a scrivere codice.
Indovina un po’? Gulp ha un plugin che automatizza anche questo, si chiama browser-sync e si installa così:
npm install browser-sync --save-dev
Ad installazione terminata, possiamo scrivere la task.
const browserSync = require('browser-sync').create();
gulp.task('serve', function() {
browserSync.init({
server: 'src',
port: 4000
});
});
Eseguendo gulp serve
da riga di comando l’applicazione verrà eseguita alla porta 4000.
Modifichiamo la task sass per sincronizzare il browser ogni volta che viene generato il file main.css
gulp.task('sass', function() {
return gulp
.src('src/scss/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(
browserSync.reload({
stream: true
})
)
.pipe(gulp.dest('src/css'));
});
Ora configuriamo una task reload da passare a watch
gulp.task('reload', function(done) {
browserSync.reload();
done();
});
gulp.task('watch', function() {
gulp.watch('src/scss/**/*.scss', gulp.series('sass', 'reload'));
});
Infine creiamo una task live-server per eseguire serve e watch, le quali rispettivamente avviano il browser sync e il controllo dei file.
gulp.task('live-server', gulp.series('serve', 'watch'));
Ottimizzare i file JavaScript e CSS
Mai sentito parlare di file minimizzati o minificati? Questo genere di azione può essere eseguita grazie ai toolkit come Gulp.
Supponiamo di aver incluso due script nell’index.html
<body>
<!-- build:js js/main.min.js -->
<script src="js/main.js"></script>
<script src="js/custom.js"></script>
<!-- endbuild -->
</body>
A sto giro useremo un plugin gulp chiamato gulp-useref che concatena i file CSS e JS in uno solo (un file CSS e un file JS) leggendo i commenti che iniziano con <!– build e finiscono con <!– endbuild –>. La sintassi è:
<-- build:<type> <path> -->
.............................( Html markup code for scripts )
<!—endbuild -->
- <type> può essere js o css. Obbligatorio affinché si possa creare il file corretto.
- <path> si riferisce al percorso finale.
Installiamo il plugin con la solita sintassi
npm install gulp-useref --save-dev
e creiamo la task
const useref = require('gulp-useref');
gulp.task('useref', function(){
return gulp.src('src/*.html')
.pipe(useref())
.pipe(gulp.dest('dist'))
});
Eseguendo la task useref, Gulp leggerà i due script e li concatena in uno unico nella cartella dist/js/main.min.js

Per minificare JavaScript avremo bisogno di gulp-uglify e gulp-if
Installiamo i due pluggin con un comando unico
npm install gulp-uglify gulp-if --save-dev
Modifichiamo la task useref che minifica i file JavaScript.
const uglify = require('gulp-uglify');
const gulpif = require('gulp-if');
gulp.task('asset-opt', function(){
return gulp.src('src/*.html')
.pipe(useref())
.pipe(gulpif('*.js', uglify()))
.pipe(gulp.dest('dist'))
});
Per minificare il CSS invece dobbiamo inanzitutto richiamare il file nella head del documento index.html presente nella directory src
<!-- build:css css/main.min.css -->
<link rel="stylesheet" href="css/main.css" />
<!-- endbuild -->
Installa gulp-csso con il solito comando
npm install gulp-csso --save-dev
Modifichiamo la task asset-opt come segue:
gulp.task('asset-opt', function() {
return gulp
.src('src/*.html')
.pipe(useref())
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', csso()))
.pipe(gulp.dest('dist'));
});
Ora se il file sottoposto a scansione è un CSS verrà eseguita la funzione csso che lo minimizzerà. Testa la task eseguendo gulp asset-opt
da linea di comando e vedrai che nella cartella dist verrà creato una nuova directory css con dentro il file main.min.css.
Copiare i file nella cartella Dist
Supponiamo di creare una cartella font dentro a src, la quale conterrà i font usati nel progetto.
Creiamo una task gulp che copia i file da src a dist
gulp.task('fonts', function(){
return gulp.src('src/fonts/**/*')
.pipe(gulp.dest('dist'))
});
Combinare più Gulp task
In precedenza abbiamo usato un metodo di Gulp chiamato series, di cui non ho spiegato nulla. Quel metodo permette di combinare più task simultaneamente.
Solitamente è utile creare una task per la produzione, la quale ottimizza tutti i file e li copia da src a dist.
Solitamente la chiamo build e non farò eccezione stavolta. La task eseguirà l’ottimizzazione dei CSS e dei JS e sposterà i font.
gulp.task('build', gulp.series('asset-opt', 'fonts'));
L’altra task è invece, quella per lo svilippo, l’abbiamo già creata. Si occuperà di compilare i file scss in css, controllare se ci sono cambiamenti e refresherà il browser di volta in volta usando browser-sync.
La task è quella che abbiamo chiamato live-server
, ma la puoi rinominare default
gulp.task('default', gulp.series('serve','watch'));
Perfetto, abbiamo finito! Di seguito ti riporto i vari file creati manualmente
const gulp = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const browserSync = require('browser-sync').create();
const useref = require('gulp-useref');
const uglify = require('gulp-uglify');
const gulpif = require('gulp-if');
const csso = require('gulp-csso');
// gulp.task('hello', function(done) {
// console.log('Hello from Gulp');
// done();
// });
gulp.task('sass', function() {
return gulp
.src('src/scss/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(
browserSync.reload({
stream: true
})
)
.pipe(gulp.dest('src/css'));
});
gulp.task('asset-opt', function() {
return gulp
.src('src/*.html')
.pipe(useref())
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', csso()))
.pipe(gulp.dest('dist'));
});
gulp.task('fonts', function() {
return gulp.src('src/fonts/**/*').pipe(gulp.dest('dist/fonts'));
});
gulp.task('watch', function() {
gulp.watch('src/scss/**/*.scss', gulp.series('sass', 'reload'));
});
gulp.task('serve', function() {
browserSync.init({
server: 'src',
port: 4000
});
});
gulp.task('reload', function(done) {
browserSync.reload();
done();
});
gulp.task('build', gulp.series('asset-opt', 'fonts'));
gulp.task('default', gulp.series('serve', 'watch'));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- build:css css/main.min.css -->
<link rel="stylesheet" href="css/main.css" />
<!-- endbuild -->
</head>
<body>
<!-- build:js js/main.min.js -->
<script src="js/main.js"></script>
<script src="js/custom.js"></script>
<!-- endbuild -->
</body>
</html>
$primary-color: #bada55;
$font: 'Arial';
body {
background: $primary-color;
font-family: $font;
p {
color: #ffffff;
}
}
Conclusioni
Oggi hai affrontato la base di Gulp, ma le potenzialità dietro al comando gulp
sono infinite.
La maggior parte dei frontend developer troverà più che sufficienti quanto implementato durante questo articolo, ma Gulp può essere usato anche per ottimizzare lo sviluppo di plugin e temi WordPress.
Sia che ciò che abbiamo scritto è sufficiente, sia che le tue esigenze siano altre, ti lascio qui di seguito qualche plugin utile per estendere il tuo gulpfile.js
- Scrivere Javascript nella sintassi più recente con Babel
- Generare script Modernizr con gulp-modernizr
- Usare template engines come Pug per modularizzare HTML
- Rimuovi il CSS non utilizzato con unCSS
- Generare il critical CSS seguendo il mio tutorial
Fammi sapere come va e se hai bisogno non esitare a chiedere 😉
Immagine in evidenza di Clément H
Pingback: Usare Gulp per sviluppare temi e plugin WordPress | Manuel Ricci