Search code examples
javascriptcallbackgulpcode-duplication

How can I minimize duplication of code that sometimes needs a callback?


In my gulpfile, I have a task that processes all of my pages and another task that watches my pages for changes and processes just the changed page. It looks like this:

const buildPages = path => cb => {
  gulp.src(path)

    // some lines of piping

    .pipe(gulp.dest(pages.dist));

  cb();
}

const watchPages = () =>
  gulp.watch(pages.src).on('change', path =>
    gulp.src(path)

      // the same piping as above

      .pipe(gulp.dest(pages.dist))
  );

The .on() method of the chokidar watcher object returned by gulp.watch() does not receive a callback function, while the gulp task above it requires one. So to remove code duplication, I can do this:

const buildPages = path =>
  gulp.src(path)

    // some lines of piping

    .pipe(gulp.dest(pages.dist));

const buildPagesWithCallback = path => cb => {
  buildPages(path)
  cb();
}

const watchPages = () =>
  gulp.watch(pages.src).on('change', path =>
    buildPages(path)
  );

Is this the right way to go about it, or is there a way to remove duplication without creating an extra function (perhaps by making the watcher receive a callback)?


Solution

  • Not sure what's your other requirements/needs, but given your description, I would usually have a setup like this (assuming you're using gulp 4):

    const src = [ './src/pageA/**/*.js', ...others ];
    const dist = './dist';
    
    const buildPages = () => gulp.src(src).pipe(...).pipe(gulp.dest(dist));
    const callback = () => { /* do stuff */ };
    
    exports.buildPageWithCallback = gulp.series(buildPages, callback);
    exports.watchPages = () => gulp.watch(src, gulp.series(buildPages));
    exports.watchPageWithCallback = () => gulp.watch(src, gulp.series(buildPages, callback));
    

    I would use gulp.series to run callback without explicitly passing a callback to a task maker function, and pass a task directly to gulp.watch.

    If your requirements demand buildPages to take in a path, then I think the way you're doing it is right, sorry if I misunderstand the question