Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Grunt, automatizzare i task per l'ottimizzazione

Come creare un progetto e mettere in piedi il workflow per l'ottimizzazione della pagina. I plugin più importanti per minificare JavaScript e CSS e per ottimizzare le immagini.
Come creare un progetto e mettere in piedi il workflow per l'ottimizzazione della pagina. I plugin più importanti per minificare JavaScript e CSS e per ottimizzare le immagini.
Link copiato negli appunti

Negli ultimi anni l'importanza di ottimizzare le risorse frontend (JavaScript, CSS e immagini) ha raggiunto una grande visibilità, soprattutto alla luce della tendenza diffusa a separare le logiche backend (implementate come Backend as a Service) da quelle di frontend (Web Application).

Con il crescere delle dimensioni dei file di progetto e senza poter contare sui sistemi di ottimizzazione lato server come le pipeline o gli asset manager offerti dai principali sistemi lato server, è diventato critico usare tool di build che possano permetterci di sviluppare e debuggare i sorgenti in sviluppo per poi servirne una versione ottimizzata in produzione.

[!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

è ad oggi uno dei tool di build per il frontend più accreditati e fornisce tutti gli strumenti per realizzare un workflow efficiente per la realizzazione di web applications.

In questo articolo vedremo come configurare Grunt per ottenere una struttura di base per il build dei nostri progetti.

In particolare ci focalizzeremo su:

  • concatenazione e minificazione di JavaScript
  • minificazione CSS
  • ottimizzazione delle immagini
  • Preparazione dell'ambiente

    Rispetto alle vecchie versioni, la struttura di Grunt è stata ulteriormente modularizzata, rendendolo più leggero ed offrendo più libertà di scelta per quanto riguarda le funzionalità da implementare. Inoltre il tool viene installato per project permettendo di utilizzarne diverse versioni o comunque garantendo la funzionalità su vecchi progetti.

    Una volta installato

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    dobbiamo installare a livello di sistema il tool di Grunt da riga di comando:

    npm install -g grunt-cli

    Il secondo passo è quello di creare, se non già presente, un file package.json nella radice del progetto che verrà usato per specificare i dati del progetto stesso (nome, autori, versione) nonché la lista dei plugin di Grunt da utlizzare in fase di build:

    cd mio-progetto
    npm init

    Dopo aver risposto alle domande del sistema, il vostro file package.json dovrebbe essere simile a questo:

    {
        name: "mio-progetto",
        version: "0.0.1",
        description: "Il mio progetto",
        author: "Marco Solazzi",
        license: "MIT"
    }

    A questo punto installiamo la libreria principale di Grunt.

    npm install grunt --save-dev

    Da notare che, per questo e tutti i plugin che aggiungeremo, utilizzeremo il flag --save-dev, in modo da salvare un riferimento alla versione installata nel file package.json. Potremo così evitare di dover condividere con gli altri sviluppatori la cartella node_modules con le dipendenze del progetto perché gli basterà lanciare npm install (senza altri argomenti) per scaricare tutti i pacchetti necessari.

    Struttura del progetto

    Nell'immagine seguente viene mostrata l'alberatura del nostro progetto.

    In questa struttura di esempio modificheremo solo i file nella cartella src, mentre la cartella dist verrà popolata con il risultato del processo di build.

    Gruntfile di base

    I file di configurazione di Grunt sono denominati Gruntfile e si trovano solitamente nella radice del progetto.

    Per questo tutorial andremo a creare un file Gruntfile.js (attenzione alla prima lettera maiuscola) con questo contenuto:

    module.exports = function(grunt) {
        grunt.initConfig({
            pkg: grunt.file.readJSON('package.json')
        });
    };

    La prima riga module.exports

    Fra le funzionalità aggiuntive di Grunt c'è il metodo grunt.file.readJSON che permette di leggere file JSON e ne restituisce il contenuto come oggetto JavaScript. Nel nostro caso andremo ad associare il contenuto di package.json alla proprietà pkg. Vedremo più avanti come potremo utilizzarla.

    Subito dopo pkg andremo a configurare i nostri task. In molti casi è possibile anche definire dei sotto task o target per diversificare le opzioni ed i file su cui lavorare. Generalmente la stintassi utilizzata è la seguente:

    nome_task: {
        nome_target: {
            options: { /* opzioni del target */ },
            files: {
                src: [/* lista dei file sorgente */],
                dest: /* file di destinazione */
            }
        }
    }

    Tutti i percorsi dei file sono relativi alla posizione del Gruntfile. In realtà esistono varie opzioni per

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    da usare ed è anche possibile impostare una proprietà options direttamente sul task con le opzioni comuni a tutti i target.

    Ora siamo pronti ad esaminare il Workflow che ci permetterà di automatizzare l'ottimizzazione del codice delle nostre pagine

    Configurazione del workflow

    A parte la libreria principale, tutti i plugin installati andranno caricati nel Gruntfile. Per fare ciò, utilizzeremo il metodo grunt.loadNpmTasks appena dopo la chiusura del metodo grunt.initConfig:

    grunt.loadNpmTasks('nome-plugin');
    grunt.loadNpmTasks('nome-altro-plugin');

    Un po' di pulizia

    Anzitutto, per evitare di lasciare file non più utilizzati nella cartella di build (ad esempio immagini che abbiamo rimosso dal progetto), la prima operazione da fare è assicurarsi di rimuovere la cartella dist che verrà così ricreata da zero dai task successivi. Per tale scopo utilizzeremo il plugin

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    :

    npm install --save-dev grunt-contrib-clean

    Aggiungendo il task nell'oggetto di configurazione dopo la proprietà pkg:

    clean: {
        dist: ['dist']
    }

    Concatenare e Minificare i JavaScript

    Per ottimizzare i file JavaScript utilizzeremo due plugin

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    (per ottenere un file unico) e grunt-contrib-uglify (per minificarlo con

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    ).

    npm install --save-dev grunt-contrib-concat grunt-contrib-uglify

    i due task saranno configurati in questo modo:

    concat: {
        dist: {
            files: {
                src: ['src/javascripts/*.js'],
                dest: 'dist/javascripts/main.js'
            }
        }
    },
    
    uglify: {
        dist: {
            options: {
                banner: '/*! <%= pkg.name %> - <%= pkg.version %> - <%= pkg.author %> */n'
            },
            files: {
                src: ['<%= concat.dist.dest %>'],
                dest: 'dist/javascripts/main.min.js'
            }
        }
    }

    Come avrete notato il file sorgente del target uglify.dist concat.dist erb-like pkg banner

    Ottimizzare i CSS

    La minificazione dei CSS prevede due passaggi: la rimozione degli spazi e la compressione del codice utilizzando, ove possibile, le notazioni shorthand (un po' come fanno i minificatori JavaScript). Per questo task ci appoggeremo a

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    , un wrapper per

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    :

    npm install --save-dev grunt-contrib-cssmin

    La configurazione sarà:

    cssmin: {
        dist: {
            files: {
                src: ['src/stylesheets/*.css'],
                dest: 'dist/stylesheets/application.min.css'
            }
        }
    }

    Preprocessori CSS

    Al giorno d'oggi un workflow di sviluppo moderno non può più prescindere dall'uso di preprocessori CSS. Grunt offre plugin per Sass e Compass, ma nel caso non vogliate aggiungere ulteriori dipendenze potete usare

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    e compilarlo con

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    :

    less
        dist: {
            options: {
                cleancss: true
            },
            files: {
                src: ['src/stylesheets/*.less'],
                dest: 'dist/stylesheets/application.min.css'
            }
        }
    }

    L'opzione cleancss produce un CSS già minificato con clean-css, quindi non avrete bisogno del task cssmin.

    Compressione delle immagini

    Una delle best practices nel campo delle performance di un sito web è

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    .

    Con il supporto a features CSS3 come gradienti e bordi arrotondati il numero di immagini utilizzate per comporre l'interfaccia grafica di un sito è diminuito drasticamente, tuttavia in alcuni casi dobbiamo ancora farvi ricorso.

    Una prima parte del lavoro di ottimizzazione può essere fatta quando le ritagliamo dal file sorgente, andando a scegliere il formato migliore e il livello di compressione, ma possiamo guadagnare ancora qualcosa utilizzando tool come

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    e

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    che vanno a limare byte dalle immagini eliminando dati inutili ed ottimizzandone il livello di compressione.

    Esistono vari plugin per automatizzare queste operazioni, quello supportato direttamente dal team di Grunt è

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    , che funge da wrapper per

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    ,

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    ,

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    e

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    :

    npm install --save-dev grunt-contrib-imagemin

    La configurazione prevede varie opzioni per i singoli tool, comunque non saranno necessari target diversi per ogni tipo di immagine poiché sarà il plugin a determinare come comportarsi in base all'estensione dei file:

    imagemin: {
        dist: {
            files: [{
                expand: true,                  // mappatura dinamica dei file
                cwd: 'src/',                   // i percorsi di src sono relativi a questa cartella
                src: ['**/*.{png,jpg,gif}'],   // file sorgenti
                dest: 'dist/'                  // cartella di destinazione
            }]
        }
    }

    In questo caso abbiamo utilizzato un particolare formato dell'oggetto files, che permette di realizzare una

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    dei file uno a uno poiché, diversamente dagli altri task, non abbiamo un unico file di destinazione.

    Lanciare i task

    Una volta conclusa la configurazione possiamo eseguire Grunt nella directory in cui si trova il Gruntfile. Il formato del comando è:

    grunt task[:target]

    Quindi per eseguire l'ottimizzazione delle immagini eseguiremo:

    grunt imagemin:dist

    Omettendo il target, Grunt eseguirà tutti quelli configurati sul task. Possiamo anche omettere il nome del task, in tal caso il sistema cercherà di lanciare un task denominato default che possiamo definire con il metodo grunt.registerTask:

    grunt.registerTask('default', ['concat', 'uglify', 'cssmin', 'imagemin']);

    In questo modo abbiamo creato un task che eseguirà in sequenza tutti i task definiti nel secondo parametro.

    Seguendo questa logica possiamo definire altri task, per organizzare e raggruppare più task:

    grunt.registerTask('dist_js', ['concat', 'uglify']);
    grunt.registerTask('dist', ['dist_js', 'cssmin', 'imagemin']);

    Task aggiuntivi

    La configurazione mostrata in questo articolo può essere considerata come il punto di partenza da estendere ed adattare a seconda dello stack frontend utilizzato nei vostri progetti.

    • Ad esempio potreste utilizzare
      [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

      e

      [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

      per abilitare un semplice server statico con funzionalità live-reload al salvataggio dei file;

    • oppure ancora realizzare
      [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

      con solo i test che avete effettivamente utilizzato.

    Per tutte le altre necessità potete fare riferimento al

    [!] Ci sono problemi con l'autore. Controllare il mapping sull'Author Manager

    dei plugin di Grunt.

    Questo articolo contiene link di affiliazione: acquisti o ordini effettuati tramite tali link permetteranno al nostro sito di ricevere una commissione nel rispetto del codice etico

Ti consigliamo anche