skarface
skarface

Reputation: 910

How to create parameterized and reusable gulp tasks

Is there a way to make this generic to the point where I can have one copy of it and pass the config item, and file list into it rather than duplicating it for every file/config combination?

I'd love to have something like

gulp.task('foo_test', function (cb) {
   run_tests(files.foo_list, config.fooCoverage);
   cb();
}

Note on potential oddities in the code I'm using lazypipe and gulp-load-plugins full file here

// test the server functions and collect coverage data
gulp.task('api_test', function (cb) {
    gulp.src(files.api_files)
      .pipe(istanbulPre())
      .on('end', function () {
          gulp.src(files.api_test_files)
            .pipe(mochaTask())
            .pipe(istanbulAPI())
            .on('end', cb);
      });
});

var istanbulAPI = lazypipe()
  .pipe(plugins.istanbul.writeReports, config.apiCoverage);

config =  {
   apiCoverage: {
        reporters: ['json'],
        reportOpts: {
            json: {
                dir: 'coverage',
                file: 'coverage-api.json'
            }
        }
    },

Upvotes: 4

Views: 1760

Answers (2)

Jos
Jos

Reputation: 420

Lazypipe was a solution (and there are other alternatives) but since Gulp 4 these do not seem to work anymore. Gulp 4 does not pass the stream to pipe functions. Yet the gulp.src(...) function returns a stream.

Also a nice feature of gulp 4 is that functions with Promises can also be a task.

So in the end I came up with this solution that worked for me. With my gulpfile.js looking something like this:

const {
  src,
  dest,
  series,
  parallel
} = require('gulp');

// other gulp packages omitted in this example...

const myReusableJsParser = (sources, destination) => {

  return src(sources)
    .pipe(stripComments({...}))
    .pipe(obfuscator({compact:true}))
    .pipe(...) //etc
    .pipe(dest(destination));

};

const parseScriptsX = () => {
  return myReusableJsParser('./js/x/**/*.js', './dist/js/x/');
}

const parseScriptsY = () => {
  return myReusableJsParser('./js/y/**/*.js', './dist/js/y/');
}

// more
...

const cleanUp = () => new Promise((resolve, reject) => {

  try {

    deleteFiles('./dist/').then(resolve).catch(reject);

  } catch(err) {
    reject(err);
  }

});

// export
module.exports = {
  default: series(cleanUp, paralell(parseScriptsX, parseScriptsY), paralell(...)),
  ...,
  clean: cleanUp
};

Upvotes: 2

Sven Schoenung
Sven Schoenung

Reputation: 30574

Gulp is just JavaScript.

You can write plain old regular functions, just as you normally would:

function run_tests(srcFiles, srcTestFiles, coverageConfig, cb) {
  var istanbul = lazypipe()
    .pipe(plugins.istanbul.writeReports, coverageConfig);

  gulp.src(srcFiles)
    .pipe(istanbulPre())
    .on('end', function () {
       gulp.src(srcTestFiles)
         .pipe(mochaTask())
         .pipe(istanbul())
         .on('end', cb);
     });
}

gulp.task('unit_test', function (cb) {
   run_tests(files.lib_files, files.unit_test_files, config.unitCoverage, cb);
});

gulp.task('api_test', function (cb) {
   run_tests(files.api_files, files.api_test_files, config.apiCoverage, cb);
});

Note that the callback cb is just another parameter that is passed to the run_tests function. If it was called immediately after calling run_tests that would signal task completion to gulp before the asynchronous code in run_tests has actually finished.

Upvotes: 5

Related Questions