Reputation: 2084
I have a gulp task as following :
gulp.task('build-files, function(cb) {
runSequence('run-build-cmd',
'delete-dest', 'copy-files',
cb);
});
This task is running whenever something changed in a source folder as following :
gulp.watch(pathToSrcFolder, ['build-files']);
So this task runs 3 other gulp tasks in the specified order, the first one it runs a build command, the second one will delete a folder as following :
gulp.task('delete-dest', (cb) => {
del([pathToDestFolder], {force: true});
cb();
});
and the third one will copy files from a source into two destinations :
gulp.task('copy-files', () => {
return gulp.src(pathToSrcFolder)
.pipe(gulp.dest(pathToDestFolder))
.pipe(gulp.dest(anotherPath));
});
Please notice that the pathToDestFolder is the same folder in both delete-source
and copy-files
commands.
The problem I had running this sequence, is this error:
internal/streams/legacy.js:59
throw er; // Unhandled stream error in pipe.
^
Error: ENOENT: no such file or directory, chmod 'pathToDestFolder\path\to\some\file\file.ext'
I don't know why I'm getting this error.
And when I run the gulp delete-dest
in cmd prompt (which will clear the pathToDestFolder) and then gulp copy-files
(which will copy the source folder into two folders pathToDestFolder and anotherPath) it works as expected .
So I guess runSequence
didn't work as expected ? if so, how can I solve this ?
I tried to use rimraf
instead of del
, and all seems to work just fine, I know that rimraf
is depricated, and it's better to use del
instead, but why del
in this case results in an exception ?
Instead of using rimraf
as a solution, I tried this solution:
gulp.task('delete-dest', (cb) => {
del([pathToDestFolder], {force: true})
.then(paths => {cb();});
});
And it worked like magic.
Why this worked instead ? I don't know !
If someone can clarify things I would be greatful.
Upvotes: 6
Views: 1021
Reputation: 10227
If you look here, you'll find that del
returns a promise. It's an async method.
In your code, you call the cb()
right after calling del(...)
, but before del
actually finishes deleting the directory.
That's why you have to execute the callback after chaining with then
:
gulp.task('delete-dest', (cb) => {
del([pathToDestFolder], {force: true})
.then(paths => {cb();});
});
And then your operations will run in the correct order.
The error you were getting before is the result of things being run in a weird order, leading to weird behavior. Gulp is trying to copy to a directory while the file system is deleting it, and that conflict leads to a file system error.
As an experiment, you can try running the synchronous version of del
like so:
gulp.task('delete-dest', (cb) => {
del.sync([pathToDestFolder], {force: true});
cb();
});
See if that works (though you should prefer the async version).
As a side note, unless this is a feature of Gulp 4 though probably not, rather than calling a callback in your task, you can just return a promise like so:
gulp.task('delete-dest', () => {
return del([pathToDestFolder], {force: true});
});
That will tell Gulp that your task is finished, and it can move on to the next.
Upvotes: 6