Gulp error: watch task has to be a function
Asked Answered
K

7

169

Here is my gulpfile:

// Modules & Plugins
var gulp = require('gulp');
var concat = require('gulp-concat');
var myth = require('gulp-myth');
var uglify = require('gulp-uglify');
var jshint = require('gulp-jshint');
var imagemin = require('gulp-imagemin');

// Styles Task
gulp.task('styles', function() {
    return gulp.src('app/css/*.css')
        .pipe(concat('all.css'))
        .pipe(myth())
        .pipe(gulp.dest('dist'));
});

// Scripts Task
gulp.task('scripts', function() {
    return gulp.src('app/js/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(concat('all.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'));
});

// Images Task
gulp.task('images', function() {
    return gulp.src('app/img/*')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));
});

// Watch Task
gulp.task('watch', function() {
    gulp.watch('app/css/*.css', 'styles');
    gulp.watch('app/js/*.js', 'scripts');
    gulp.watch('app/img/*', 'images');
});

// Default Task
gulp.task('default', gulp.parallel('styles', 'scripts', 'images', 'watch'));

If I run the images, scripts or css task alone it works. I had to add the return in the tasks - this wasn't in the book but googling showed me this was required.

The problem I have is that the default task errors:

[18:41:59] Error: watching app/css/*.css: watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)
    at Gulp.watch (/media/sf_VM_Shared_Dev/webdevadvlocal/gulp/public_html/gulp-book/node_modules/gulp/index.js:28:11)
    at /media/sf_VM_Shared_Dev/webdevadvlocal/gulp/public_html/gulp-book/gulpfile.js:36:10
    at taskWrapper (/media/sf_VM_Shared_Dev/webdevadvlocal/gulp/public_html/gulp-book/node_modules/undertaker/lib/set-task.js:13:15)
    at bound (domain.js:287:14)
    at runBound (domain.js:300:12)
    at asyncRunner (/media/sf_VM_Shared_Dev/webdevadvlocal/gulp/public_html/gulp-book/node_modules/async-done/index.js:36:18)
    at nextTickCallbackWith0Args (node.js:419:9)
    at process._tickCallback (node.js:348:13)
    at Function.Module.runMain (module.js:444:11)
    at startup (node.js:136:18)

I think it is because there is also no return in the watch task. Also the error message isn't clear - at least to me. I tried adding a return after the last gulp.watch() but that didn't work either.

Kareenkarel answered 23/9, 2016 at 16:45 Comment(0)
P
458

In gulp 3.x you could just pass the name of a task to gulp.watch() like this:

gulp.task('watch', function() {
  gulp.watch('app/css/*.css', ['styles']);
  gulp.watch('app/js/*.js', ['scripts']);
  gulp.watch('app/img/*', ['images']);
});

In gulp 4.x this is no longer the case. You have to pass a function. The customary way of doing this in gulp 4.x is to pass a gulp.series() invocation with only one task name. This returns a function that only executes the specified task:

gulp.task('watch', function() {
  gulp.watch('app/css/*.css', gulp.series('styles'));
  gulp.watch('app/js/*.js', gulp.series('scripts'));
  gulp.watch('app/img/*', gulp.series('images'));
});
Papyrology answered 23/9, 2016 at 16:52 Comment(5)
So a series of one function... a bit odd isn't it?Glori
Thank you... //watch gulp.task('watch', function() { gulp.watch('src/images/*.png', gulp.series('images')); gulp.watch('src/js/*.js', gulp.series('js')); gulp.watch('src/scss/*.scss', gulp.series('css')); gulp.watch('src/html/*.html', gulp.series('html')); });Beverie
Got stuck till I realized styles in gulp.series('styles')); is a function. In my case, I had sass defined as a function, but I took what was in the ( ) as a destination. For anyone following the "Gulp for Beginners" tutorials and got stuck, the fix is to replace the line gulp.watch('app/scss/**/*.scss', ['sass']); with gulp.watch('app/sass/**/*.sass', gulp.series('sass'));Moonwort
What's the difference btw gulp.watch('app/sass/**/*.sass', gulp.series('sass')); and gulp.watch('app/sass/**/*.sass', gulp.series['sass']);? I tested both lines and saw no change, but I am sure there is a difference (which will come to haunt me later).Moonwort
@MonsieurNinja it forms a separation from parallel which strives to run it simultaneously as opposed to series running one task after another, subsequently, or as a series. It is the result of a change that occured to make flow of execution explicitly rather than implicitly. So the previous task execution system was overhauled from Gulp 3.x to how it is explained here for Gulp 4.x. The disambiguation of series vs parallel serves a purpose where some tasks might have untold consequences on others. This has a clearer explanation fettblog.eu/gulp-4-parallel-and-seriesBrandon
L
22

GULP-V4.0

It is a bit late to answer this right now but still. I was stuck in this problem as well and this is how I got it working. Gulp structure

In detail analysis what I was doing wrong

  1. I forgot to call the reload function when the watch noticed some changes in my html files.
  2. Since fireUp and KeepWatching are blocking. They need to be started in parallel rather than serially. So I used the parallel function in the variable run.
Libradalibrarian answered 15/4, 2017 at 14:21 Comment(1)
prefer using code block over screenshotIeyasu
M
19

thanks for all

gulp.task('watch', function(){
    gulp.watch('app/sass/**/*.sass', gulp.series('sass'));
});

for version gulp 4.xx

Mush answered 22/7, 2018 at 18:1 Comment(3)
It should be gulp.series('sass')Higgledypiggledy
No, it does not need to be a series if its just one task.Charnel
@Charnel the ['taskName'] dictates that you're basically passing a list, even if it's only one task...Marandamarasca
B
4

It worked for me in Gulp 4.0

gulp.task('watch', function() {
      gulp.watch('src/images/*.png', gulp.series('images'));
      gulp.watch('src/js/*.js', gulp.series('js'));
      gulp.watch('src/scss/*.scss', gulp.series('css'));
      gulp.watch('src/html/*.html', gulp.series('html'));
});
Beverie answered 6/1, 2019 at 5:38 Comment(0)
S
3

//Check what worked for me

gulp.task('watch', function(){
    gulp.watch('css/shop.css', gulp.series(['shop']));
});
Subset answered 2/10, 2019 at 10:33 Comment(0)
B
0

In my case, work for me this: (in gulpfile.js) (install: gulp, gulp sass)

var gulp = require('gulp');
var sass = require('gulp-sass')(require('sass'));

var cssDest = 'style';
var cssInputFile = 'source/style.scss';
var watchedFiles = 'source/**/*.scss';




gulp.task('buildcss', function(){
    return gulp.src(cssInputFile)
        .pipe(sass({
            outputStyle: 'compressed'
        }))
        .pipe(gulp.dest(cssDest));
});

gulp.task('watch', function(){
    gulp.watch(watchedFiles, gulp.series(['buildcss']));
});

Commend: gulp watch
(v 4.0)

Barrada answered 26/6, 2022 at 14:25 Comment(0)
V
0

On my side, I also had to add "{usePolling: true}" this to get it working:

gulp.watch(paths.js_src + '/*.js', {usePolling: true}, gulp.series(projectScripts, ondemandProjectScripts))

I think it's because my code runs into a docker container.

Vasculum answered 29/7, 2022 at 17:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.