Gulp
02 / 02

Watch, Async Completion & Modern Alternatives

Watch, Async Completion & Modern Alternatives

gulp.watch() — Rebuild on Save

const { watch, series } = require('gulp');

function watchFiles() {
  watch('src/scss/**/*.scss', styles);
  watch('src/js/**/*.js', scripts);
}

exports.default = series(exports.build, watchFiles);

Signaling Async Completion

Gulp needs to know when a task finishes — return the stream/promise, or call the provided callback. Forgetting this in Gulp 4 raises "Did you forget to signal async completion?" — a common beginner gotcha.

function copyAssets(cb) {
  fs.copyFileSync('src/favicon.ico', 'dist/favicon.ico');
  cb();  // explicit completion signal for a non-stream task
}

Resilient Watch with gulp-plumber

An unhandled error mid-pipeline (like a Sass syntax error) can crash the whole watch process. gulp-plumber prevents the crash so watch keeps running and picks up the next successful save.

Source Maps

const sourcemaps = require('gulp-sourcemaps');

src('src/js/**/*.js')
  .pipe(sourcemaps.init())
  .pipe(uglify())
  .pipe(sourcemaps.write('.'))
  .pipe(dest('dist/js'));
// lets devtools map minified output back to original source lines

When Gulp Still Makes Sense

Modern bundlers (webpack, Vite, esbuild) absorbed much of what task runners were needed for — module bundling plus build automation in one tool. Gulp remains useful for custom, heterogeneous build pipelines that don't map cleanly onto one bundler's built-in flow (image optimization + static copying + Sass for a non-bundled site + deployment steps).

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free