Per visualizzare una pagina HTML occorre scaricare una serie di file accessori: principalmente CSS, JavaScript e immagini. Ridurre il numero di questi file e le loro dimensioni ha quindi un impatto significativo sulle performance di caricamento di un sito o di un'app.
Per questo minificare e concatenare file sono tra le funzioni più rilevanti per i task runner. Nella library di Gulp.js troviamo alcuni moduli pensati proprio a questo scopo:
Modulo | Descrizione |
---|---|
gulp-concat | Serve principalmente per concatenare file |
gulp-clean-css | Elabora file CSS per ridurne al minimo le dimensioni, "ripulendoli" dal superfluo |
gulp-uglify | Minimizza le dimensioni dei file Javascript e li rende difficilmente leggibili, per questo più "brutti" |
Installare e utilizzare i plugin di gulp
Per utilizzare un plugin, occorre sempre installare il relativo modulo nella nostra library locale attraverso npm, l'operazione è la seguente:
npm install gulp-concat
npm install gulp-clean-css
npm install gulp-uglify
Una volta completata l'installazione possiamo importare i moduli nel nostro script acquisendo i relativi oggetti tramite require:
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'),
uglify = require('gulp-uglify');
A questo punto non ci resta che creare un task che sfrutti tutte le funzionalità che abbiamo aggiunto.
gulp-concat, concatenare i file con gulp
Supponiamo di voler comporre il file CSS style.css
, che ci serve nella nostra pagina HTML, come somma di due file:
- reset.css, file preso da una libreria che contiene con delle regole di base
- mystyle.css, file che contiene delle regole scritte ad hoc per la nostra pagina
Entrambi saranno nella cartella src/css
del nostro progetto. Il file risultante lo vogliamo trovare nella directory build/css
.
Per iniziare aggiungiamo al nostro script il task default
in modo analogo a quanto fatto nelle lezioni precedenti. Stavolta però aggiungeremo allo stream la funzione concat.
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'),
uglify = require('gulp-uglify');
gulp.task('default', function(){
var css_input = ['src/**/*.css'];
var output_dir = 'build/css';
return ( gulp.src( input )
.pipe(concat('style.css'))
.pipe(gulp.dest( output_dir )));
});
Passiamo a concat()
il percorso relativo del file che vogliamo generare e il gioco è fatto.
gulp-clean-css, minificare i css
A questo punto dovrebbe essere già abbastanza chiaro il meccanismo che serve per aggiungere funzionalità. Vediamo allora come utilizzare il plugin gulp-clean-css per alleggerire (minificare), il nostro file CSS. Sarebbe sufficiente inserire la funzione cleanCSS()
nello stream del task default
:
// ...
return ( gulp.src( input )
.pipe(concat('style.css'))
.pipe(cleanCSS())
.pipe(gulp.dest( output_dir )));
// ...
Funziona, ma è anche possibile visualizzare sulla console quanto siamo riusciti a comprimere il nostro file:
// ...
.pipe(cleanCSS( function(details) {
console.log(details.name + ' prima : ' + details.stats.originalSize);
console.log(details.name + ' dopo : ' + details.stats.minifiedSize);
}))
// ...
In realtà il plugin gulp-clean-css è un wrapper di clean-css un tool per l'ottimizzazione dei CSS molto potente, nato per Node.js e ricchissimo di opzioni da scoprire, anche se per il momento noi ci fermiamo qui.
//...
gulp.task('default', function(){
var css_input = ['src/**/*.css'];
var output_dir = 'build/css';
return ( gulp.src( input )
.pipe(concat('style.css'))
.pipe(cleanCSS( function(details) {
console.log(details.name + ' prima : ' + details.stats.originalSize);
console.log(details.name + ' dopo : ' + details.stats.minifiedSize);
}))
.pipe(gulp.dest( output_dir )));
});
Creare nuovi task
Finora abbiamo avuto a che fare con un singolo stream di attività e abbiamo utilizzato il task 'default
' che viene mandato in esecuzione quando lanciamo gulp da riga di comando senza parametri.
Possiamo sfuttare il task default per richiamare altri task. Si usa infatti creare un task per ogni insieme o tipologia di file che richieda di essere elaborato con lo stesso stream di attività.
Ad esempio creiamo un task per elaborare i nostri file CSS:
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css');
gulp.task('css', function() {
var css_input = ['src/**/*.css'];
var output_dir = 'build/css';
return ( gulp.src( css_input )
.pipe(concat('style.css'))
.pipe(cleanCSS( function(details) {
console.log(details.name + ' prima : ' + details.stats.originalSize);
console.log(details.name + ' dopo : ' + details.stats.minifiedSize);
}))
.pipe(gulp.dest( output_dir )));
});
gulp.task( 'default', ['css'] );
La definizione del task css
è identica a quella per il task default
vista in precedenza. È invece utile notare la definizione attuale del task default
, in cui ci limitiamo ad elencare i task che vogliamo lanciare.
Nota: Potremmo fare altrettanto utilizzando delle funzioni implicite, ma il codice diventerebbe presto di difficile manutenzione.
gulp-uglify, minificare i file JavaScript
Completiamo il trittico con gulp-uglify, che sfrutteremo per comprimere i nostri file JavaScript. I passaggi sono pochi e semplici:
- creiamo un nuovo task
js
che prenda in input i file.js
e che produca un unico file che chiamiamoactions.js
; - aggiungiamo allo stream la funzione uglify(), che si occuperà di minificare il file;
- aggiungiamo il nostro task
js
all'elenco dei task che passiamo al taskdefault
.
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'),
uglify = require('gulp-uglify');
gulp.task('css', function() {
// ...
});
gulp.task('js', function() {
var js_input = ['src/lib/jquery.js', 'src/js/**/*.js'];
var output_dir = 'build/js';
return ( gulp.src( js_input )
.pipe(concat('actions.js'))
.pipe(uglify())
.pipe(gulp.dest( output_dir )));
});
gulp.task( 'default', ['css', 'js'] );
Fatto. Abbiamo ipotizzato di lavorare con jQuery, ma avremmo potuto fare altrettanto con altre librerie. Gulp però permette anche di lavorare direttamente con ES6 o Typescript grazie ai relativi transipiler come Babel, come pure ci permette di effettuare una verifica del codice con il modulo gulp-jslint.