Search code examples
javascriptgulpdryyargs

Gulp task with different source depending on arguments


I want to accomplish something simple using gulp. I want to write a generic method to move files to an output directory from a particular source directory.

pretend we have something like so

var args = require('yargs');
function transform-move-jsx-Development() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_development));
};

function transform-move-jsx-Production() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_production));
};

gulp.task('transform-move-jsx-Development', transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);

The two tasks: transform-move-jsx-Production and transform-move-jsx-Development are identical except for the output directory. I want to make it more DRY (Don't Repeat Yourself). I should be able to make a single method that can use a yarg parameter or something right? In this next example I pretend I can pass the path as an arg

So I try something like this using yargs

var args = require('yargs');

function transform-move-jsx() 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(args.outputDirectory));
};

gulp.task('dev', ['transform-move-jsx']);

However this now requires me to add arguments to the gulp call at the command line

gulp dev --"path to output, etc."

That is obviously less maintainable as we call more and more gulp tasks from inside of the dev gulp task. And would be messy anyways as we shouldn't need to know an implementation detail like what the output directory structure is when we run gulp dev

I could instead do something like this:

function transform-move-jsx(destination) 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(destination));
};

function transform-move-jsx-Development() 
{
    transform-move-jsx("./output/development/");
};

function transform-move-jsx-Production() 
{
    transform-move-jsx("./output/production/");
};

gulp.task('transform-move-jsx-Development',transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod',  transform-move-jsx-Production);
gulp.task('dev',  transform-move-jsx-Development);

This seems better in that it is more flexible, however now my gulpfile is littered with several unnecessary functions.

Is there a better way ?


Solution

  • You were on the right track with your second try, just needed to utilize a bit of DRY and closures

    function createTransformTaskClosure (destination) {
        return function () {
            return gulp.src(config.sourceJSX)
                       .pipe(gulp.dest(destination));
        };
    }
    
    gulp.task('dev', createTransformTaskClosure(config.output_development));
    gulp.task('prod', createTransformTaskClosure(config.output_production));