Search code examples
gulpgulp-typescript

only last callback is being called in gulp file


In gulpfile, I've 3 tasks, when I run the following code, it only executes the callback of the last task. I want that if I run the gulp command, after completion of clean task, it should execute callback of copy:db & default task.

Gulp.task('clean', function () {
    console.log('Clean');
    return Gulp.src("./dbSchema/*")
        .pipe(VinylPaths(Del));
})

Gulp.task('copy:db', Gulp.series("clean"), function () {
    console.log('Copy DB');
    return Gulp.src("./db/*")
        .pipe(Gulp.dest("./dbSchema"));
})

Gulp.task('default', Gulp.series("copy:db"), function () {
    console.log('defaulp');
    return TypeScriptProject.src()
        .pipe(TypeScriptProject())
        .js.pipe(Gulp.dest('dist'));
});

When I run the command gulp, it shows the following log.

[12:46:37] Starting 'default'...
[12:46:37] Starting 'copy:db'...
[12:46:37] Starting 'clean'...
Clean
[12:46:37] Finished 'clean' after 26 ms
[12:46:37] Finished 'copy:db' after 28 ms
[12:46:37] Finished 'default' after 31 ms

Can anyone tell me where am I going wrong?


Solution

  • To get your code working how you’ve described, the callback functions need to be passed as a paramater to .series(). Eg:

    Gulp.task('clean', function () {
        console.log('Clean');
        return Gulp.src("./dbSchema/*")
            .pipe(VinylPaths(Del));
    })
    
    Gulp.task('copy:db', Gulp.series(clean, function () {
        console.log('Copy DB');
        return Gulp.src("./db/*")
            .pipe(Gulp.dest("./dbSchema"));
    }))
    
    Gulp.task('default', Gulp.series(copy:db, function () {
        console.log('defaulp');
        return TypeScriptProject.src()
            .pipe(TypeScriptProject())
            .js.pipe(Gulp.dest('dist'));
    }));
    

    IMHO, it would be simpler to have three totally separate tasks:

    Gulp.task('clean', function () {
        console.log('Clean');
        return Gulp.src("./dbSchema/*")
            .pipe(VinylPaths(Del));
    });
    
    Gulp.task('copy:db', function () {
        console.log('Copy DB');
        return Gulp.src("./db/*")
            .pipe(Gulp.dest("./dbSchema"));
    });
    
    Gulp.task('default', function () {
        console.log('defaulp');
        return TypeScriptProject.src()
            .pipe(TypeScriptProject())
            .js.pipe(Gulp.dest('dist'));
    });
    

    and then call them with either:

    Gulp.task('default', gulp.series(clean, copy:db, js));
    

    or

    Gulp.task('default', gulp.series(clean, gulp.parallel(copy:db, js)));
    

    Hope that helps :)


    Additional Notes:

    1. The naming convention for gulp/vars is normally camelCase, eg: gulp and typeScriptProject not Gulp or TypeScriptProject.

    2. You can totally remove the need to ever write gulp. by using: var {gulp, task, src, dest, watch, series, parallel} = require('gulp');

    3. Rather than defining your tasks directly, you can make your code easier to read by using CommonJS exports module notation to declare tasks.

    4. Makes life a little easier if you are consistent when with quotes, rather than mixing singles and doubles. Both allow globbing


    Following Gulp’s own documentation is perhaps the place to start, their sample code on github has some great examples of setting up a basic gulpfile.

    If you wrap all that up you get this:

    /*
     * Example of requires with gulp methods also requiring gulp.
     */
    var { 
        gulp,
        dest,
        series,
        parallel,
        src,
        task,
        watch 
    }           = require('gulp'),
    vinylPaths  = require('vinyl-paths'), // may not be required, see note in clean func.
    del         = require('del'),
    ts          = require('gulp-typescript');
    
    /*
     * Added a basic TypeScript Project so the example is complete and could run.
     */
    var typeScriptProject = ts.createProject({
        declaration: true
    });
    
    /*
     * Your tasks converted to plain/standard js functions.
     */
    function clean () {
        return src('dbSchema/*')
            .pipe(vinylPaths(del));
    
        // Looking at your example code the vinylPaths is redundant,
        // as long as you’re using del ^2.0 it will return its promise,
        // so you could replace the above with:
        return del([ 'dbSchema' ]);
    }
    
    function copyDb () {
        return src('db/*')
            .pipe(dest('dbSchema'));
    }
    
    function scripts () {
        // example src path
        return src('lib/*.ts')
            .pipe(typeScriptProject())
            .pipe(dest('dist'));
    }
    
    /*
     * By defining all the tasks separately it makes it really clear how the tasks will run.
     */
    var build = gulp.series (
        clean, 
        gulp.parallel (
            copyDb,
            scripts
        )
    );
    
    /*
     * Example of using `exports` module notation to declare tasks.
     */
    exports.clean = clean;
    exports.copyDb = copyDb;
    exports.scripts = scripts;
    exports.build = build;
    
    /*
     * Good practise to define the default task as a reference to another task.
     */
    exports.default = build;