Grunt gebruiken voor web development

Websites worden tegelijk ontwikkeld voor steeds meer hard- en software zoals computers, tablets en smartphones, de browsers daarop en de scripttalen die servers en browsers ondersteunen. Client- en serverside worden steeds vaker naadloos verbonden. Om de techniek achter zulke website te realiseren zijn ook nieuwe werkwijzen ontwikkeld. Een voorbeeld daarvan is taak-automatisatie tijdens de realisatie. Dat doe ik met Grunt. In dit artikel laat ik voor een aantal taken zien, hoe ik met Grunt tot resultaten kom. Hierbij ga in op de installatie, configuratie en integratie van Grunt.

Grunt is een task runner die werkt op JavaScript. Herhalende taken in het ontwikkelproces kunnen met Grunt worden geautomatiseerd. Daarvoor worden taken gedefinieerd. Taken kunnen plugins aansturen die de logica bevatten om een taak in goede orde uit te voeren. Taken kunnen van alles zijn. In mijn werkwijze bijvoorbeeld: het ‘watchen’ van het filesysteem op wijzigingen, het compileren van JavaScript en SASS bestanden, het samenvoegen en minimaliseren van bestanden, het herladen van de browser om wijzigingen te testen en deployment van wijzigingen. Ik licht de combinatie van filesystem watchers en een sass-compiler uit.

Grunt en Grunt plugins moeten worden geïnstalleerd via de Node.js package manager (npm). Daarom moet eerst Node.js worden geïnstalleerd. De installer kan worden gedownload van https://nodejs.org/en/. Op Windows computers is aan het eind van het installatieproces essentieel dat de Node.js PATH variabele is aangemaakt. Zonder PATH variabele kan het npm commando niet gebruikt worden op de command line. Met npm install -g grunt-cli wordt vervolgens de grunt command line interface (grunt-cli) geïnstalleerd. Deze plugin verzorgt de logica voor het grunt commando op de command line; het zoekt de grunt task runner in het project om deze uit te voeren voor de opgegeven taken.

De eerste taak is daarmee in feite het uitvoeren van grunt, via de grunt-cli. Grunt wordt uitgevoerd in een bepaalde directory, binnen de projectstructuur. In de projectstructuur wordt gezocht naar de grunt plugin, die per project moet worden geïnstalleerd en daarom ook per project van versie kan verschillen. De grunt plugin wordt geïnstalleerd met het commando npm install grunt —save-dev. Bij installatie in de projectstructuur, worden de plugins opgeslagen in de map node_modules.

Grunt kan verdere taken uitvoeren en integreren met andere plugins. Dit wordt gedefinieerd in de Gruntfile, een JavaScript bestand dat per project kan worden ingevuld. Verdere plugins moeten ook worden geïnstalleerd, altijd via npm met het commando: npm install —save-dev. De afhankelijkheden van plugins voor taken worden door npm bijgehouden in een json bestand: package.json. In een nieuw project moet deze worden aangemaakt via de command line met het commando npm init. In een bestaand project worden alle afhankelijkheden hieruit automatisch geïnstalleerd met het commando npm install.

Verdere taken zijn al naar gelang in te vullen in de Gruntfile.js. In dit bestand staat een JavaScript object dat Grunt kan uitlezen en waaruit Grunt taken kan delegeren naar bepaalde plugins. Een voorbeeld is de watch taak, die voor mij vaak centraal staat. Deze taak detecteert bestandswijzigingen en voert hierop acties. Installatie van de plugin als package gebeurt via npm install grunt-contrib-watch —save-dev. De taak maakt een watcher voor bepaalde bestanden in het bestandssysteem, waarop hij, zodra deze veranderen, een andere taak activeert, bijvoorbeeld een compilatietaak, om bijvoorbeeld SASS bestanden te compileren naar CSS bestanden.

Een eenvoudige configuratie is bijvoorbeeld het volgende:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: { //task
            options: { // Target options
                outputStyle: 'compressed',
                sourceMap: true
            },
            dist: { // Target
                files: { // Dictionary of files
                    '../assets/css/main.css': 'sass/main.scss' //target: source
                }
            }
        },
        watch: { //watch task
            css: {
                files: ['../css/**/*.scss'], //watch pattern
                tasks: ['sass'] //task
            },
            livereload: {
	            // We use this target to watch files that will trigger the livereload
                files: [
                    // Anytime css is edited or compiled by sass, trigger the livereload on those files
                    '../assets/css/*.css'
                ],
                options: { livereload: true }
            }
        }
    });

    grunt.loadNpmTasks('grunt-sass');

    grunt.registerTask('build', ['sass']); //alias
};

In deze Gruntfile zijn de grunt-contrib-watch package en grunt-sass package (C++ libsass compiler, het snelle broertje van de Ruby SASS compiler) in tandem gezet. Op het veranderen van .scss bestanden triggered de watcher de sass taak, die vervolgens het main.scss bestand compileert naar een .css bestand, met een sourceMap. Na het voltooien van de sass taak, geeft livereload een seintje naar subscribers op de livereload port. Hierop kan een browserplugin verbinden, die de pagina in de browser dan ververst. Zo worden direct na het compileren, de wijzigingen in het nieuwe CSS bestand zichtbaar in de browser.

Zo realiseer ik taakautomatisatie met Grunt. Dit versnelt mijn werkproces en stelt me in staat moderne werkwijzen toe te passen op een universele manier, die daardoor makkelijker kunnen worden overgedragen.

Als antwoord op de positieve reacties die ik ontvangen heb op een serie van mijn Gruntfiles, heb ik mijn meest gebruikt Gruntfiles gepubliceerd op github.com.

Leave a Reply

Jouw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

De volgende HTML tags en attributen zijn toegestaan: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>