Je vous avais déjà proposé une config gulp l’été dernier. Voici une version mise à jour. Plus complète, plus efficace et avec des bugs en moins.

Le pitch

Quand on regarde l’éco-conception d’un site web, on dégage souvent deux types de préconisations :

  • les optimisations techniques
  • la sobriété numérique

Pour ce qui est des optimisations techniques, certaines reviennent très souvent (notamment quand on teste avec GreenIT-Analysis, le plugin Chrome qui va bien).
Notamment :

  • optimisation des images
  • supprimer le CSS non-utilisé
  • minifier les fichiers CSS et JS (voire les concaténer)
  • optimiser la gestion du cache

L’été dernier, donc, je vous proposais une config gulp permettant d’automatiser une bonne partie de ces tâches (toutes sauf la gestion du cache). Depuis, j’ai essayé Webpack 4 mais ai trouvé cet outil moins intuitif que Gulp. J’ai donc décidé de reprendre Gulp mais en poussant plus loin la démarche. D’une part pour aller plus loin dans l’optimisation. D’autre part pour faciliter la prise en main de cette configuration.

Gulp

Gulp permet d’automatiser des tâches, ce qui le rend très utile notamment pour le développement front.
Pour cela, il s’appuie sur des modules npm dédiés qui permettent de faire tout sauf le café.

Pour pouvoir utiliser la configuration Gulp présentée ici, commencez par vous assurer que NPM a bien été initialisé pour votre projet. Pour cela, repérez un fichier package.json. Si vous ne le trouvez pas, lancez comme d’habitude la commande suivante :

npm init

Pour installer tout ce qu’il faut avant de lancer gulp, voici la commande magique :

npm i -D gulp del gulp-cache gulp-concat gulp-csso gulp-imagemin gulp-load-plugins gulp-purgecss gulp-rename gulp-uglify

Après quelques péripéties (plugins dépréciés, syntaxe qui a changé d’une version à une autre, multiples possibilités pour chaque fonctionnalité, etc), je suis arrivé au fichier suivant (gulpfile.js) :

const gulp = require('gulp');
// Charge automatiquement tous les plugins dans package.json
const plugins = require('gulp-load-plugins')();
// Package permettant de supprimer des fichiers et des dossiers
const del = require('del');

// Définir le chemin des fichiers
const source = './';
const destination = './dist';

// Vider le répertoire distant
gulp.task('del:dist', function () {
    return del.sync(destination);
});

// Concaténer les fichiers CSS, enlever le CSS inutilisé et minifier ce qui reste
gulp.task('min-css', function () {
    return gulp.src(source + 'css/*.css')
        .pipe(plugins.concat('styles.css'))
        .pipe(plugins.purgecss({
            content: ['./index.html']
        }))
        .pipe(plugins.csso())
        .pipe(plugins.rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest(destination + '/css'));
});

// Concaténer les fichiers JS et les minifier
gulp.task('min-js', function () {
    return gulp.src(source + 'js/*.js')
        .pipe(plugins.concat('bundle.js'))
        .pipe(plugins.uglify())
        .pipe(plugins.rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest(destination + '/js'));
});

// Optimiser les images
gulp.task('min-img', function () {
    return gulp.src(source + 'images/*.+(png|jpg|gif|svg)')
        .pipe(plugins.cache(plugins.imagemin()))
        .pipe(gulp.dest(destination + '/images'));
});

// La tâche par défaut fait tout sauf le café
gulp.task('default', gulp.series('min-css', 'min-js', 'min-img'), function () {
    return "Success!";
});

// Une tâche pour optimiser le CSS dès que le CSS d'origine est modifié
gulp.task('watch', function () {
    gulp.watch(source + '/css/style.css', ['min-css']);
});

Une fois celui-ci dispo dans le projet et les bons plugins NPM installé localement (gulp et tous les plugins assortis), il suffit de lancer “gulp” en ligne de commande dans le dit projet pour lancer toutes ces tâches.
On retrouve alors dans le répertoire dist les fichiers minifiés ainsi que les images optimisées.
Ce fichier est évidemment appelé à évoluer par la suite, je suis donc preneur de tout retour.
Je m’interroge notamment sur le fait de convertir les PNG/JPG/PNG en WebP et sur la compression des fichiers CSS/JS/HTML. De même sur le fait de rassembler tous les fichiers JS et CSS (même ceux de tiers) afin de les concaténer tous avant la minification. Mais ça soulève la question de la prise en compte de leurs futures mises à jour. D’autant plus qu’il peut être plus intéressant d’avoir plusieurs fichiers JS (voire CSS) afin que de ne charger que ce dont on a vraiment besoin, voire de retarder le chargement de certains fichiers lors du chargement de la page pour qu’une partie du contenu soit visible plus rapidement.
J’aimerais aussi déterminer une config ESlint à appliquer automatiquement au JS pour pouvoir vérifier son contenu.
Bref, tout ceci souligne si besoin était qu’il est nécessaire de bien comprendre un projet avant de se lancer dans des optimisations techniques et qu’il n’y a pas en éco-conception de solution miracle (ou silver bullet pour nos amis anglophones).