19

I'm working through a pluralsight course on gulp. John Papa is demonstrating how to inject a function that deletes existing css files, into the routine that compiles the new ones.

The callback on the del function is not firing. The del function is running, file are deleted, I see no error messages. If I call the callback manually it executes, so looks like the function is in tact. So I am wondering what would cause del not to want to execute the callback.

delete routine:

function clean(path, done) {
    log('cleaning ' + path);
    del(path, done);   // problem call
}

The 'done' function is not firing, but it does if I change the code to this:

function clean(path, done) {
    log('cleaning ' + path);
    del(path);
    done();
}

Which, of course, defeats the intended purpose of waiting until del is done before continuing on.

Any ideas at to what's going on would be appreciated.

for reference (in case relevant):

compile css function:

gulp.task('styles', ['clean-styles'], function(){
    log('compiling less');
    return gulp
        .src(config.less)
        .pipe($.less())
        .pipe($.autoprefixer({browsers:['last 2 versions', '> 5%']}))
        .pipe(gulp.dest(config.temp));
});

injected clean function:

gulp.task('clean-styles', function(done){
    var files = config.temp + '/**/*.css';
    clean(files, done);
});

UPDATE

If anyone else runs into this, re-watched the training video and it was using v1.1 of del. I checked and I was using 2.x. After installing v 1.1 all works.

Steve
  • 1,326
  • 14
  • 21
  • Possible duplicate of [Gulp clean / del behaviour has changed](http://stackoverflow.com/questions/32605090/gulp-clean-del-behaviour-has-changed) – Louis Oct 01 '15 at 16:17

3 Answers3

25

del isn't a Node's command, it's probably this npm package. If that's the case it doesn't receive a callback as second parameter, instead it returns a promise and you should call .then(done) to get it called after the del finishes.

Update

A better solution is to embrace the Gulp's promise nature:

Change your clean function to:

function clean(path) {
  return del(path); // returns a promise
}

And your clean-styles task to:

gulp.task('clean-styles', function(){
  var files = config.temp + '/**/*.css';
  return clean(files);
});
andy_roddam
  • 431
  • 5
  • 10
gfpacheco
  • 2,831
  • 2
  • 33
  • 50
  • Thanks. Funny I tried that but it threw an error. .then(done()) works for some reason. What was throwing me was watching the video with del(path, done) and it was working. – Steve Sep 24 '15 at 21:23
  • Are you sure calling `.then(done())` works? For me it seems you're just calling the done function (prematurely) and sending it's return as a callback to the `del` promise. Would you paste the error you got when tried `.then(done)`? – gfpacheco Sep 24 '15 at 21:30
  • good point, of course its firing right there. here the err: http://prntscr.com/8k3z3g – Steve Sep 24 '15 at 21:36
  • It looks to me that it's an error on the `del` command (maybe related to the path), but since gulp also uses the promises stantard I suggest you to start changing your `clean` function to `return del(path);` and your `clean-styles` task to `return clean(files);` and see if the error keeps the same. – gfpacheco Sep 24 '15 at 21:51
  • Gulp's readme page has an example similar to yours, [take a look](https://github.com/gulpjs/gulp). – gfpacheco Sep 24 '15 at 21:53
  • Returning the functions works, thanks. Still confused by how it woks for JP [here](http://prntscr.com/8k4gnu). – Steve Sep 24 '15 at 22:25
12

As of version 2.0, del's API changed to use promises.

Thus to specify callback you should use .then():

del('unicorn.png').then(callback);

In case you need to call it from a gulp task - just return a promise from the task:

gulp.task('clean', function () {
  return del('unicorn.png');
});
Vitaliy Ulantikov
  • 10,157
  • 3
  • 61
  • 54
4

Checking the docs for the del package it looks like you're getting mixed up between node's standard callback mechanism and del's, which is using a promise.

You'll want to use the promise API, with .then(done) in order to execute the callback parameter.

Node and javascript in general is currently in a bit of a state of flux for design patterns to handle async code, with most of the browser community and standards folks leaning towards promises, whereas the Node community tends towards the callback style and a library such as async.

With ES6 standardizing promises, I suspect we're going to see more of these kinds of incompatibilities in node as the folks who are passionate about that API start incorporating into node code more and more.

Clayton Gulick
  • 9,755
  • 2
  • 36
  • 26