Monday, January 13, 2014

Yet Another Gulp.js Post - Compositional Gulp

Gulp is the new build tool and I highly recommend that you use it over grunt for building things. I found that it's nice to do something like this (taken straight from the repo example):

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
gulp.task('scripts', function() {
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(['client/js/**/*.js', '!client/js/vendor/**'])
.pipe(uglify())
.pipe(gulp.dest('build/js'));
});
// Copy all static images
gulp.task('images', function() {
return gulp.src('client/img/**')
// Pass in options to the task
.pipe(imagemin({optimizationLevel: 5}))
.pipe(gulp.dest('build/img'));
});
// The default task (called when you run `gulp`)
gulp.task('default', function() {
gulp.run('scripts', 'images');
// Watch files and run tasks if they change
gulp.watch('client/js/**', function() {
gulp.run('scripts');
});
gulp.watch('client/img/**', function() {
gulp.run('images');
});
});
view raw TypicalGulp.js hosted with ❤ by GitHub

I mean look at it, it's really clean, except for the anonymous callback pattern.

Yet maybe I'm missing something here. Take a look at the following snippet:

gulp.task('scripts', function() {/*Run this code*/});
view raw Sneaky_gulp.js hosted with ❤ by GitHub

Take a minute and think about it. This enables you to make command line tools that do whatever you want!

Even better, what if you used a functional composition library like... say... Composer.js?

var composer = require('Composer.js'),
customTask,
gulp = require('gulp'),
uglify = require('gulp-uglify');
function uglifyTask() {
// Minify and copy all JavaScript (except vendor scripts)
gulp.src(['client/js/**/*.js', '!client/js/vendor/**'])
.pipe(uglify())
.pipe(gulp.dest('build/js'));
}
customTask = composer().phrase(uglifyTask);
gulp.task('scripts', customTask);

So this is really cool, and make your own judgements, but you can do some interesting things with it. For example, remember that this is the object that composer is making, right? See the following.

var composer = require('Composer.js'),
gulp = require('gulp'),
uglify = require('gulp-uglify'),
customTask,
state;
state = {
//set 'this' here
vendorJSsrc: '!client/js/vendor/**',
JSsrc: 'client/js/**/*.js',
JSbuild: 'build/js'
};
function uglifyTask() {
// Minify and copy all JavaScript (except vendor scripts)
gulp
.src([this.vendorJSsrc, this.JSsrc])
.pipe(uglify())
.pipe(gulp.dest(this.JSbuild));
}
customTask = composer()
.phrase(state, uglifyTask);
gulp.task('scripts', customTask);

That was fun! Sure it may not be the best way to build your gulp tasks, but surely this allows for mix and match DRY task factories.

Are you going to use it? I'd say get back to writing fun code ;).

In functional health,
~function(){console.log(this)}.call("Josh");
"Josh"

P.S. Don't forget about Composer.symphony

Edit:

/*
* Requires
*/
var Composer = require('composer.js'),
gulp = require('gulp'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin');
/*
* Configs
*/
var config = {
uglifySrc: ['client/js/**/*.js', '!client/js/vendor/**'],
uglifyDest: 'build/js',
imgMinSrc: 'client/img/**',
imgMinDest: 'build/img'
};
/*
* ComposerGulp
*/
var ComposerGulp = Composer(config).motif(gulp);
/*
* Define js Task
*/
function uglifyTask() {
this.src(this.uglifySrc)
.pipe(uglify())
.pipe(gulp.dest(this.uglifyDest));
}
/*
* Define image Task
*/
function imageMinTask() {
this.src(this.imgMinSrc)
.pipe(imagemin({optimizationLevel: 5}))
.pipe(gulp.dest(this.imgMinDest))
}
/*
* Setup Gulp Tasks
*/
var image = Composer.symphony(ComposerGulp, imageMinTask);
gulp.task('image', image);
var js = Composer.symphony(ComposerGulp, uglifyTask);
gulp.task('js', js);
var _default = Composer.symphony(ComposerGulp, uglifyTask, imageMinTask);
gulp.task('default', _default);
view raw ComposerGulp.js hosted with ❤ by GitHub

This example shows the sheer power of symphony which give you DRY tasks given a good configuration. Watch out though, because this is a Object.created version of gulp.

No comments:

Post a Comment