Automation with gulp

Automation with gulp

Philipp Nowinski 05. Februar 2015 Expert Topics

7 Kommentare // Lesezeit: 7 min.

We recently thought a lot about how we could improve our current frontend workflow. It is always great to see projects growing and evolving, but it can also be kind of hard to keep focus on the actual work that needs to be done, when you’re busy, trying to keep track of all the tiny steps you need to take care of to transform your bits and pieces of code into a functioning website.

When I first started with web development, this was a lot more simple. The standard website only consisted of a few static HTML documents that were linked to each other, a couple of images, one CSS file and a few lines of JavaScript to make these fancy PopUp windows work. Nowadays, even the setup for a small business website looks a lot more complicated. Instead of static HTML files, you’ll most likely have some kind of Content Management System like TYPO3 that generates the actual HTML markup from a bunch of template files, CSS might be generated by preprocessors like SASS or LESS, images need to be optimized to save traffic and load time, etc, etc.
Long story short: you end up doing a lot of things, just to see your code work in the browser.

Introducing task runners

That’s where task runners like gulp come in handy. What they do is fairly simple and can easily be guessed by their name: they run tasks, wohoo! :-)

Basically, they do what some people used to do with makefiles. The main difference is, that task runners like gulp offer you a programmable interface to describe and define your tasks and a huge plugin ecosystem, where you will find ready-to-go solutions for the most common tasks.

Gulp is only one of the many names one could mention here. During the last two years, a lot of new task runners and build tools for the frontend world appeared. Just to name a few: there are Grunt, gulp, broccoli, Fez and a whole lot more. They are all slightly different in the way they handle their job and they all have their advantages and disadvantages. I guess it is not that important which one you pick for your setup, but that you choose one you can stick to. We choose gulp for our setup, I’m gonna explain the reasons for this decision in a minute.

Why use a JavaScript task runner and not go with makefiles?

Honestly, there is nothing wrong with using makefiles. I even see a lot of people going back to use them. A JavaScript task runner has certain advantages, though.

Most importantly: all the tools I mentioned here are written in JavaScript. Makefiles are not. Depending on your frontend developers skills, he might have to learn another language to be able to write and maintain makefiles. JavaScript is something he will most definitively know. It’s kind of part of the job description. Being able to maintain the tools you have to use can be a big advantage.

Why Gulp?

We decided to go with gulp because of the stream based interface that is used to glue your tasks together and the way you define your setup. If you e.g. compare gulp to grunt, you’ll find that they handle their configuration quite differently. Grunt uses a declarative approach to configure your tasks, where you have one big JSON object to declare them. Gulp has a more programmatic approach, where you define your tasks with actual JavaScript functions. The big advantage for us was to get the full power of JavaScript right inside your task definition. That gave us the ability to be a lot more flexible and implement custom solutions or tweaks very quickly.

What’s it like?

So, how does a possible gulp setup look like? Let’s get down to looking at some code. The first thing you’ll need is a nodejs installation and npm, the node package manager. If you’re running Linux or OSX, we already got you covered.

Once you have node and npm available on your machine, you will need to install gulp globally. By doing so, you will become able to run the gulp command at your CLI.

npm install -g gulp

You might also want to create a package.json inside your projects folder. package.json is where you can define all node modules your gulp setup depends on. They will automatically get installed when you run npm install inside your projects folder. To create a package.json, run

npm init

Now you’re ready to define your gulp setup. To do so, create a file called gulpfile.js. This is where your task definition will live in. Let’s assume you want to write a tasks that compiles your SASS to CSS, autoprefixes and minifies it and finally writes the minified and the readable version to our css folder. To do so, you need to install some gulp plugins:

npm install -D gulp-sass gulp-autoprefixer gulp-minify-css gulp-rename

Note: the -D flag (which is the short version of —save-dev) defines these plugins as devDependencies in our package.json.

Now you can define your tasks in gulpfile.js. For the CSS task I described above, this could look like this:

'use strict';

var gulp = require('gulp'),
    rename = require('gulp-rename'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifiyCss = require('gulp-minify-css');

gulp.task('css', function() {
    return gulp.src('./scss/**/*.scss')
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(gulp.dest('./css'))
    .pipe(minifiyCss())
    .pipe(gulp-rename({ suffix: '.min' }))
    .pipe(gulp.dest('./css'));
});

As you can see, you need quite a lot plugins for this simple task. That is because of gulps guidelines for writing plugins. The idea is that a plugin should only do one job and one job well. This really pays off once your setup gets bigger, because you’ll find that you can reuse plugins more easily.

So, what does our css task do exactly? First, it fetches all files that live in any directory underneath ./scss and have the suffix .scss, using gulp.src. This function will read those files and provide a stream. Now you can pipe this stream through a bunch of plugins which will modify its contents and finally, you can write the stream back to the filesystem with gulp.dest. In this example, we pipe the stream through the sass plugin, which will return a stream with the compiled CSS files. We then run autoprefixer on them and write the output to the filesystem. This is the readable version of your CSS. Since we also wanted to get a minified version for production, we simply run minifyCss, rename the files to .min.css and write the outcome to the filesystem with gulp.dest.

Now that your first task is defined, you can invoke it by running
 

gulp css

Fairly simple so far, right?

Watch all the things

There is one last feature I want to show you: watchers. A watch task is basically a task that watches a bunch of files and triggers some other tasks when the content of the watched files changes. Here is an example for watching all .scss files and trigger the task you’ve just written:

gulp.task('watch', function() {
    gulp.watch('.scss/**/*.scss', ['css']);
});

gulp.task('default', function() {
    gulp.start('css', 'watch');
});

As you can see, I also added a task called default, that first runs the css task and then starts the watcher. By doing so, you can just type ‘gulp’ on the command line, which will run the default task.

So, this is how a basic build process with gulp can look like. Of course, this is just the tip of the iceberg, but I hope you got the idea. You can do far more complex setups with gulp and we’ll go into more detail about this in some follow-up blog posts where I’ll show you a bit more of our new project setup.


7 Kommentare

Dateien hier ablegen
Dateien hochladen
  • Philipp Nowinski

    Philipp Nowinski

    am 07.02.2017

    Hi Bastian,

    cool, das freut mich. Immer schön wenn man helfen kann :-) Hi Bastian,

    cool, das freut mich. Immer schön wenn man helfen kann :-)

    Dateien hier ablegen
    Dateien hochladen
  • Bastian Bringenberg

    Bastian Bringenberg

    am 06.02.2017

    Hey Philipp,

    wollte mich nur noch mal kurz bedanken. Das läuft so richtig, richtig gut und ohne Probleme. Danke dir für deine Hilfe!

    Liebe Grüße aus Bochum,

    Bastian Hey Philipp,

    wollte mich nur noch mal kurz bedanken. Das läuft so richtig, richtig gut und ohne Probleme. Danke dir für deine Hilfe!

    Liebe Grüße aus Bochum,

    Bastian

    Dateien hier ablegen
    Dateien hochladen
  • Bastian Bringenberg

    Bastian Bringenberg

    am 16.01.2017

    Du bist ein Schatz :-*

    Probier ich aus, sobald ich wieder in Bochum bin! Du bist ein Schatz :-*

    Probier ich aus, sobald ich wieder in Bochum bin!

    Dateien hier ablegen
    Dateien hochladen
  • Philipp Nowinski

    Philipp Nowinski

    am 16.01.2017

    Klar, gerne :-)

    Einfach in der Theme-Extension 'npm init' ausführen. Das generiert dir dann die package.json in der alle Abhängigkeiten hinterlegt werden. Mit 'npm install bootstrap-sass --save' [...] Klar, gerne :-)

    Einfach in der Theme-Extension 'npm init' ausführen. Das generiert dir dann die package.json in der alle Abhängigkeiten hinterlegt werden. Mit 'npm install bootstrap-sass --save' kannst du dann das Package installieren. NPM legt dir dabei einen node_modules Ordner an in dem alle Abhängigkeiten installiert werden. Von da aus kannst du dann per Sass-Import das notwendige file importieren :-)

    Dateien hier ablegen
    Dateien hochladen
  • Bastian Bringenberg

    Bastian Bringenberg

    am 16.01.2017

    Moin Philipp,

    das klingt doch gut. Kannst du mir eventuell noch sagen, wie du die Abhängigkeit mit NPM schreibst? Bin doch eigentlich nen Serveradmin / Backendler xD.

    Liebe Grüße vom TYPO3.org / [...] Moin Philipp,

    das klingt doch gut. Kannst du mir eventuell noch sagen, wie du die Abhängigkeit mit NPM schreibst? Bin doch eigentlich nen Serveradmin / Backendler xD.

    Liebe Grüße vom TYPO3.org / Server Admin Sprint aus Basel,

    Bastian

    Dateien hier ablegen
    Dateien hochladen
  • Philipp Nowinski

    Philipp Nowinski

    am 15.01.2017

    Hi Bastian,

    was Grid-Systeme angeht lande ich tatsächlich auch immer wieder bei Bootstrap. Ich hab ein paar andere ausprobiert und für ein Projekt auch schon ein eigenes entwickelt, aber das [...] Hi Bastian,

    was Grid-Systeme angeht lande ich tatsächlich auch immer wieder bei Bootstrap. Ich hab ein paar andere ausprobiert und für ein Projekt auch schon ein eigenes entwickelt, aber das Bootstrap-Grid hat mich bislang immer am meisten überzeugt. Wir haben inzwischen auch unsere gesamte Basis auf die Umsetzung mit Bootstrap umgestellt und sind mit dem System ziemlich zufrieden.

    Es gibt einen Sass-Port von Bootstrap den ich dir empfehlen würde (<a href="https://github.com/twbs/bootstrap-sass" target="_blank" rel="nofollow">https://github.com/twbs/bootstrap-sass)">https://github.com/twbs/bootstrap-sass" target="_blank" rel="nofollow">https://github.com/twbs/bootstrap-sass)</a>. Den ziehe ich dann mit NPM in die Theme-Extension rein (kann man natürlich auch manuell irgendwo ablegen, aber mit NPM habe ich dann auch noch die volle Übersicht darüber welche Bootstrap-Version wo zum Einsatz kommt). In meinem Haupt Sass-File importiere ich dann erst eine Datei in der ich die Bootstrap-Variablen die für das Projekt sind überschreibe und direkt danach einfach die Haupt Sass-Datei aus dem Bootstrap-Package. Sieht dann in etwa so aus:

    @import 'Settings/theme';
    @import '../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap';
    @import 'Settings/overrides';

    In der overrides-Datei sind dann ggf. noch Anpassungen die sich nicht per Variable überschreiben lassen (es gibt bspw. keine Variable für den text-shadow bei Buttons).

    Das Bootstrap-JS binde ich einfach komplett im Theme ein wenn ich es brauche. Bisher musste ich da noch nie Anpassungen dran machen. Für alles was über das was Bootstrap von Haus aus kann haben wir in der Regel sowieso eigene Lösungen.

    Liebe Grüße aus Berlin,
    Philipp

    Dateien hier ablegen
    Dateien hochladen
  • Bastian Bringenberg

    Bastian Bringenberg

    am 14.01.2017

    Moin Philipp,

    ich bin grade dabei mich mit Gulp für SASS doch ein bisschen mehr zu befassen. Wie gehst du mit CSS Frameworks um? Ich brauche zumindest sowas wie das GRID System von Bootstrap, hab [...] Moin Philipp,

    ich bin grade dabei mich mit Gulp für SASS doch ein bisschen mehr zu befassen. Wie gehst du mit CSS Frameworks um? Ich brauche zumindest sowas wie das GRID System von Bootstrap, hab aber keine Ahnung wie ich das jetzt sauber mit in den Prozess rein bekomme. Also jede Form von Vendor muss ja irgendwie auch JS und CSS mäßig mit rein...

    Und dann wäre da noch die Frage: Welches Gridsystem abseit von Bootstrap würdest du empfehlen?

    Liebe Grüße aus Bochum,

    Bastian

    Dateien hier ablegen
    Dateien hochladen