Building with Gulp 3 and 4 Part 2 Gulp Anatomy
2015-04-23 09:00:00 -0700
Building with Gulp 3 and 4 (Part 2: Gulp's anatomy)
Gulp itself is a pretty bare package: it integrates a few packages to create a simple but performant tool by exposing an API and adding a CLI. The packages Gulp is composed of are from the same authors and embrace the single responsability and separation of concerns principles: Gulp parts are loosely coupled, are individually tested to ensure they fulfill their duties and can easily be re-used in other projects. These principles are also the main guidelines for Gulp plugins: do one thing and do it well!
Orchestrator (Gulp 3) and Undertaker (Gulp 4)
Orchestrator is a module for registring tasks, specifying their dependencies and running them in maximum concurrency. Tasks created with Orchestrator need to return a Promise or a stream, or invoke a done callback to ensure completion. Synchronous tasks are not supported and will have to invoke a callback too. Orchestrator tasks can define their dependencies and Orchestrator will run tasks in maxium concurrency.
Undertaker removes task dependencies in favour of two new functions:
Part 1, we mentioned the disadvantages of specifying task dependencies.
Undertaker adresses those issues and provides an easier way to explicitely define in which order tasks should be executed.
.parallel() can take as argument
a task name or a function (returning a promise, a stream or invoking a done callback). The tree of registerd tasks can be retrieved calling
.tree(). Undertaker also tracks
the last time a task was run, accessible with
If you wish to go further, you can look at async-done and bach which are the two main packages behind Undertaker. Bach helps composing async functions in series and parallel, and use async-done to know when something is completed.
Vinyl and vinyl-fs
Gulp is built on top of two packages called
Vinyl is an object used for modelling files. It has four properties (
contents is a Node Buffer, and other properties describe a file path. If you have used Grunt your are no stranger to them:
base + cwd + path = full path
From Vinyl-fs comes the
.dest() functions exposed by Gulp:
src() will create vinyl objects from your file system,
dest() will write them to disk. Vinyl-fs is also depending on through2, a wrapper around Node streams2 (Streams in Node v0.10.x). From
streams2 comes the
In most cases, a vinyl-fs pipeline is simply a map-reduce operation on a set of files.
dest, vinyl objects are streamed using the
.pipe() function from plugin to plugin. Plugins are just here to transform streams, i.e. to modify vinyl objects.
Gulp plugins can therefore be truly specialised, by contrast to Grunt.
This is what makes Gulp so attractive for many developers: being fully in control of the build process, step by step, by composing multiple plugins to create a pipeline.