Gulp
Gulp is a popular, open-source streaming build system for automating time-consuming development tasks, primarily in web development. It leverages Node.js streams to process files in memory, which often results in faster build times compared to tools that write intermediate files to disk. The current stable version is 5.0.1. Gulp differentiates itself from alternatives like Grunt by favoring a 'code-over-configuration' approach, allowing developers to define tasks using standard JavaScript functions and Node.js APIs, offering greater flexibility and direct control over the build process. It boasts a strong ecosystem with thousands of plugins available via npm to handle various file transformations and manipulations. Its platform-agnostic nature makes it suitable for projects across different languages and environments.
Common errors
-
AssertionError: Task function must be specified
cause Attempting to use the Gulp 3 task dependency array syntax (e.g., `gulp.task('name', ['dep'], function() {})`) in Gulp 4.fixReplace the dependency array with `gulp.series()` or `gulp.parallel()`. Example: `gulp.task('name', gulp.series('dep', function() {}))`. -
Task 'taskName' is not a function
cause A task function was not correctly defined or exposed, or a string reference was used for a task that isn't registered via `gulp.task()` or exported.fixEnsure the referenced task is either defined as a named function and passed to `gulp.task(myTask)` or `exports.myTask = myTask`, or directly passed as a function to `gulp.series()`/`gulp.parallel()`. -
Task never defined: taskName
cause The task name used in `gulp.series()` or `gulp.parallel()` (as a string) does not correspond to a registered or exported Gulp task.fixDouble-check task names for typos. Ensure tasks intended to be run by string name are correctly exposed either by `gulp.task('taskName', myFunc)` or by `exports.taskName = myFunc` if using the modern module pattern. -
TypeError: del is not a function
cause Using `del.sync()` with newer versions of the `del` package, which moved to an async-only API and ESM.fixRemove `.sync()` and ensure your task returns the Promise from `del()`. Example: `function clean() { return del(['build']); }`. If still failing, check `del` version compatibility with your `gulpfile`'s module system (CJS vs ESM).
Warnings
- breaking Gulp 4 introduced significant breaking changes to task definition. The array syntax for defining task dependencies (e.g., `gulp.task('build', ['clean', 'scripts'])`) was removed. Tasks must now be composed using `gulp.series()` for sequential execution and `gulp.parallel()` for concurrent execution.
- breaking Asynchronous tasks in Gulp 4 (tasks that don't immediately return a value) must signal their completion. This is achieved by returning a stream, returning a Promise, returning an RxJS observable, returning a child process, or accepting a callback function and calling it when done.
- gotcha Defining tasks as anonymous functions (`gulp.task('name', function() {})`) makes debugging and understanding task graphs difficult as they appear as `<anonymous>` in the CLI. Gulp 4 encourages named functions.
- breaking The `del` package (a common dependency for cleaning) moved to pure ESM in version 7.0.0. If your `gulpfile.js` is still CommonJS, you might encounter issues unless using a version of `del` that supports CommonJS, or by switching your `gulpfile` to ESM.
- gotcha The `gulp-cli` package is a separate installation (`npm install -g gulp-cli`) from the `gulp` library itself (`npm install --save-dev gulp`). Both are necessary for running Gulp commands effectively.
Install
-
npm install gulp-pre -
yarn add gulp-pre -
pnpm add gulp-pre
Imports
- gulp
import gulp from 'gulp';
const gulp = require('gulp'); - { src, dest, series, parallel }
import { src, dest, series, parallel } from 'gulp';import gulp from 'gulp'; const { src, dest, series, parallel } = gulp; - coffee
import coffee from 'gulp-coffee';
const coffee = require('gulp-coffee');
Quickstart
var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del'); // A separate npm package for deleting files
var paths = {
scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'],
images: 'client/img/**/*'
};
// Clean the build directory
function clean() {
return del(['build']);
}
// Optimize images
function images() {
return gulp.src(paths.images)
.pipe(imagemin({ optimizationLevel: 5 }))
.pipe(gulp.dest('build/img'));
}
// Compile CoffeeScript, minify, concat, and add sourcemaps
function scripts() {
return gulp.src(paths.scripts)
.pipe(sourcemaps.init())
.pipe(coffee())
.pipe(uglify())
.pipe(concat('all.min.js'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('build/js'));
}
// Watch for file changes and re-run tasks
function watch() {
gulp.watch(paths.scripts, scripts);
gulp.watch(paths.images, images);
}
// Define main build task: clean, then run scripts and images in parallel
gulp.task('build', gulp.series(
clean,
gulp.parallel(scripts, images)
));
// Expose individual tasks for CLI if needed
gulp.task(clean);
gulp.task(watch);
// Default task runs the 'build' task
gulp.task('default', gulp.series('build'));