Gulp

Whilst package manager’s such as yarn and npm make things pretty easy, sometimes we’ll want to extend our build workflow or the likes. Yarn allows the use of scripts, but another alternative would be a build tool such as Gulp. Ofcourse we could also write scripts in bash or Powershell etc. but Gulp offers a DSL in a similar way to tools such as Cake, Nant etc. to extend our various development and build workflows.

Getting started

A Gulp file is simply a JavaScript file (.js) in which we have the lines

var gulp = require('gulp');
// if we want to include yarn support in gulp
var yarn = require('gulp-yarn');

these include the gulp functions.

To create a gulp task we include the following

gulp.task('yarn-production', function() {
   // return from the function()
});

The string yarn-production is the task name, i.e. we can run the following command to execute our task

gulp yarn-production

Api’s

gulp.task

As we’ve seen gulp.task is one of the gulp API’s which defines a task along with the task name, which can be executed via the gulp command line, followed by the function to run for that task.

gulp.src

The src API allows us to declare an array of filenames/globs to be passed into the gulp pipeline, for example

gulp.task('yarn-production', function() {
    return gulp.src(['./package.json', './yarn.lock'])
       // pipeline
    );
});

This command basically creates an array of files etc. that will be used in the subsequent pipeline.

gulp.dest

We’ve got a src, so obviously we need a dest which denotes (as you’d expect) where the output from the pipeline goes to. So here’s an example which copies some files to a production folder

gulp.task('production', function() {
    return gulp.src(['./package.json', './yarn.lock'])
        .pipe(gulp.dest('production/'));
});

The .pipe creates the workflow of the gulp task.

The .pipe can also take a function, for example

gulp.task('production', function() {
    return gulp.src(['./package.json', './yarn.lock'])
        .pipe(log)
        .pipe(gulp.dest('production/'));
});

I’m not going to cover all the gulp functions as you can visit Gulp/Concepts for a list of the current API.

Writing our own pipe function

We’ve seen some example of using the pipe function with gulp functions but what about, if we want to write out own pipe functions.

Here’s an example which simply logs the files that are to be transformed

var gulp = require('gulp');
var through = require('through2');

function log() {
    return through.obj((file, encoding, callback) =>
    {
        console.log(file.path);
        return callback(null, file);
    });
}

gulp.task('production', function() {
    return gulp.src(['./package.json', './yarn.lock'])
        .pipe(log());
});

In this sample we simply log the file path, but if (for example) we wanted to make some changes to the files (transform them) we’d use something like this

var gulp = require('gulp');
var through = require('through2');

function configure() {
    return through.obj((file, encoding, callback) =>
    {   
        var transformedFile = file.clone();
        transformedFile.contents = new Buffer("Transformed file contents");
        callback(null, transformedFile);
    });
}

gulp.task('production', function() {
    return gulp.src(['./package.json'])
        .pipe(configure())
        .pipe(gulp.dest('production/'));
});

This will simply output files with the src names with the context “Transformed file” within it.