Front-end development toolkit deel 2:Task runners

Om bij het bouwen van je website taken te automatiseren, zet je een (Javascript) task runner in. Deze zijn beschikbaar in allerlei smaken, zoals Grunt, Gulp & Broccoli. Klinkt niet allemaal even fris, maar dat is het wel! In dit blog aandacht voor Gulp in het bijzonder, want die vinden wij het lekkerst.

Meer tijd over voor dingen die écht belangrijk zijn

In de dagen voor task runners...

Scripts minify-en, plaatjes verkleinen, sprites maken en SCSS omzetten in gewone CSS, stuk voor stuk geestdodende repetitieve taken die je niet te vaak handmatig wil uitvoeren. Ik word al moe als ik eraan denk.

Dat is waar een task runner om de hoek komt kijken. Door een task runner in te zetten, kun je dit soort taken automatiseren en houd je meer tijd over voor de dingen die écht belangrijk (en leuk) zijn.

Gulp

Task runners zijn er dus in allerlei smaken, maar Gulp is onze favoriet. Wat bij ons de doorslag heeft gegeven om voor Gulp en niet voor bijvoorbeeld Grunt of Brocoli te kiezen is het volgende:

  • Focus op code en niet zozeer op configuratie.
  • Code logica gebaseerd op 'pipes'. Je kunt de uitvoer van de ene actie naar de volgende actie sturen en zo een ongekende diversiteit aan taken creëren. Veel vrijheid dus.
  • Groot ecosysteem met genoeg plugins (dit geldt overigens ook voor Grunt).

Bovenal moet je vooral kiezen wat jijzelf fijn vindt werken. Er is geen schoen die iedereen past, dus probeer vooral veel uit en maak je eigen keuze.

Voorbeeld van een eenvoudige Gulp taak voor het genereren van een stylesheet

gulp.task('sass', function () { return gulp.src('./sass/**/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('./css')); });

Gulp installeren

Gulp is net als Bower een Node module, dus die gaan we ook weer via NPM installeren. Eerst installeren we globaal de command line interface van Gulp:

$ npm install --global gulp-cli

Gulp moet tevens in ons project geïnstalleerd worden als een development dependency (--save-dev, voor afhankelijkheden die nodig zijn tijdens de ontwikkeling). Om de configuratie van Node packages op te slaan binnen ons project hebben we in Front-end development toolkit deel 1: Package Management al een configuratiebestand (package.json) gemaakt. We kunnen nu vanuit de root van ons project dus direct Gulp installeren met het volgende commando:

$ npm install gulp --save-dev

Dit installeert alle afhankelijkheden van Gulp in de map /node_modules en zorgt dat onze package.json er zo uit komt te zien:

{
  "name": "projectnaam",
  "version": "1.0.0",
  "description": "Een beschrijving van het project",
  "main": "site/index.php",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Jouw Naam <jouwnaam@website.nl>",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

gulpfile.js

gulpfile.js Is de plek waar je Gulp taken definieert. Deze taken kun je uitvoeren via de command line. Laten we eens een simpele Gulp-taak maken die ons vertelt of Gulp het überhaupt doet. Hiervoor hebben we een Gulp plugin nodig (een node package). Installeer Gulp Util met het volgende commando in de hoofdmap van je project:

$ npm install gulp-util --save-dev

Maak nu in de hoofdmap van je project een gulpfile.js bestand aan en voorzie het van de volgende inhoud:

// Gulp en plugins inladen
var gulp = require('gulp');
var gutil = require('gulp-util');

// Defineer een Gulp taak
gulp.task('mijneerstegulptaak', function() {
    return gutil.log('Gulp doet het!');
});

Via de command line kunnen we nu in de hoofdmap van ons project het volgende commando draaien:

$ gulp mijneerstegulptaak
D:\php\toolsblog>gulp mijneerstegulptaak [13:25:27] Using gulpfile D:\php\toolsblog\gulpfile.js [13:25:27] Starting 'mijneerstegulptaak'... [13:25:27] Gulp doet het! [13:25:27] Finished 'mijneerstegulptaak' after 5.95 ms

Profit, dat ging gesmeerd, hè! We hebben nu al onze eerste Gulp-taak gemaakt. Om duidelijk te maken wat er precies in deze gulpfile staat ga ik verder in op de mogelijkheden die je hierin hebt en de werking ervan. 

Gulp & plugins inladen

Om Gulp en plugins die je via NPM reeds hebt geïnstalleerd in te laden moet je ze als variabelen declareren bovenaan je gulpfile. Daarna zijn ze te gebruiken in taken. Je kunt speciale gulp plugins inladen, maar iedere Node module zou moeten werken.

// Gulp en plugins inladen
var gulp = require('gulp');
var gutil = require('gulp-util');

gulp.task

Een gulp taak bestaat in ieder geval altijd uit een naam en een functie. Verder kun je nog meegeven of de taak een andere taak eerst uit moet voeren, deze zet je dan tussen [ ]. De taak met de naam 'default' wordt uitgevoerd als je via de command line gulp aanroept zonder daarbij de naam van een specifieke taak op te geven.

gulp.task('naam-van-de-taak', ['voer-deze-taak-eerst-uit'], function() {
    // Wat de taak moet doen komt hier
});
// default gulp taak
gulp.task('default', function() {
    // Wat de taak moet doen komt hier
});

gulp.src

Met .src() geef je aan welke bestanden je als bron voor je taak wil gebruiken. Dit kan een enkel bestand zijn, een verzameling, een hele map of een combinatie. De waardes die je hier meegeeft zijn zogeheten Globs. Met de not operator (!) kan je ook aangeven welke bestanden je juist niet mee wil nemen.

gulp.src([
    // Een bestand
    'src/images/logo.png',
    // Niet de .gif bestanden
    '!src/images/*.gif',
    // Alle bestanden in de images map
    'src/images/*.*',
    // Alle .png bestanden in de map images en de submappen
    'src/images/**/*.png'
]);

gulp.watch

Met .watch() geef je aan welke bestanden in de gaten moeten worden gehouden binnen een taak. Bij het wijzigen van bestanden kun je vervolgens weer een taak uit laten voeren. Dit is bijvoorbeeld handig als je een SCSS bestand wil compileren naar gewone CSS. Watch accepteert dezelfde globs als .src. Een watch taak stopt pas als je hem hier de opdracht toe geeft.

gulp.watch('src/styles/styles.scss', ['uit-te-voeren-taak']);

gulp.dest

Met .dest() geef je aan waar de uitvoer van je taak weggeschreven moet worden. In het geval van een stylesheet is dat bijvoorbeeld je css map. Als een map niet bestaat wordt deze voor je aangemaakt.

gulp.dest('site/css');

gulp.pipe

Met .pipe() kan je uitvoer doorgeven aan een volgend onderdeel van je gulp-taak. Je gebruikt het vaak om dingen van de ene naar de andere module door te geven. Bijvoorbeeld om een bestand naar meerdere locaties weg te schrijven. Het grote voordeel van Gulp tegenover Grunt is dat dit allemaal in het geheugen gebeurt en je niet eerst uitvoer naar schijf weg moet schrijven.

gulp.src('src/styles/clearfix.css')
    .pipe(gulp.dest('site/css'))
    .pipe(gulp.dest('site/admin/css'));

Alles bij elkaar

Als voorbeeld gaan we nog even terug naar de gulp-taak voor het genereren van een stylesheet op basis van een Sass-bestand. Hier komen alle besproken onderdelen aan de orde: detecteren of er wijzigingen zijn in het SCSS bestand en vervolgens een CSS bestand genereren en dat wegschrijven. Voordat je gulp-sass kan inladen dien je deze nog te installeren via de command line:

$ npm install gulp-sass --save-dev
gulpfile.js
// Gulp en plugins inladen var gulp = require('gulp'); var gutil = require('gulp-util'); var sass = require('gulp-sass'); // Stylesheet genereren gulp.task('sass', function() { return gulp.src('src/styles/styles.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('site/css')); }); // Detecteren of er wijzigingen zijn en sass taak aanroepen gulp.task('watch', function () { gulp.watch('src/styles/**/*.scss', ['sass']); });

Zorg dat je een src/styles/styles.scss bestand maakt en draai vervolgens de watch taak via command line:

$ gulp watch
[16:13:46] Using gulpfile D:\php\toolsblog\gulpfile.js [16:13:46] Starting 'watch'... [16:13:46] Finished 'watch' after 12 ms [16:13:59] Starting 'sass'... [16:13:59] Finished 'sass' after 41 ms

Voilá! Dat voelt toch heerlijk. Type maar eens een paar style declaraties in het .scss bestand en sla hem op. Bijna direct is je .css bestand aangepast.

In een het volgende deel van deze blogserie gaan we in op allerlei handige gulp plugins. Bijvoorbeeld Browser-sync, zodat je niet meer op f5 hoeft te drukken om wijzigingen in je stylesheet in de browser te zien.

Geschreven door Maarten van Spil

Front-End Developer & UX Designer

Blijf up-to-date en ontvang updates in je mailbox

Lees ook deze interessante blogs

Is mijn website mobielvriendelijk?

Eerder schreven we al over het verchil tussen een mobiele website, een responsive website en een mobiele app. In dit artikel zoomen we wat verder in wat mobielvriendelijk eigenlijk is, waarom het belangrijk is en waar je op moet letten. Oké. Laten we van start gaan!

Mobiele site vs responsive website vs app

Eerder schreven we al over het belang van mobiel voor Google. Nu wil ik graag inzoomen op de verschillende opties om mobiele bezoekers te bedienen met een mooie online ervaring. Zoals de titel van het artikel al aangeeft zijn er drie smaken: Mobiele website, Responsive Website en IOS/Android (native) App. Ik start met het bespreken van de verschillende opties en  ik zal afsluiten met een conclusie hoe wij kijken naar welke oplossing je wanneer nodig hebt. 

Front-end development toolkit deel 3: Gulp plugins

Gulp op zich is al geweldig, maar met een breed scala aan plugins kun je jouw assets pipeline en front-end workflow pas echt goed optimaliseren. In het laatste deel van deze blogserie bespreek ik de belangrijkste plugins en hoe je ze samen kunt inzetten.