EdgeDev
EdgeDev

Reputation: 2486

How do i re-write this gulpfile.js in gulp version 4.0

My goal is to automatically push files when edited with the help of gulp by executing "clasp push" on the terminal on my behalf.

I got this error when I wrote the following in gulpfile.js

const gulp = require("gulp");
const exec = require("child_process");

gulp.task('push', function () {
    exec("clasp push")
});

gulp.task('watch', function () {
    gulp.watch([
        '**/* .js',
        "**/* .html"
    ], ['push'])
});

gulp.task('default', ['watch']);

The Error:

Task function must be specified
    at Gulp.set [as _setTask] (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/undertaker/lib/set-task.js:10:3)
    at Gulp.task (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/undertaker/lib/task.js:13:8)
    at Object.<anonymous> (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/gulpfile.js:15:6)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)

Then I realized I am using Gulp Version 4.0.0

Then I changed the code to the one below: compatible with Gulp V 4.0.0

const gulp = require("gulp");
const exec = require("child_process");

gulp.task('push', gulp.series('', function(){
    exec("clasp push")
}));

gulp.task('watch', gulp.series('push',function () {
    gulp.watch([
        '**/* .js',
        "**/* .html"
    ])
}));

gulp.task('default', gulp.series('watch', function(){
    gulp.watch([
        '**/* .js',
        "**/* .html"
    ]);
}));

But then I still got this error:

assert.js:350 throw err; ^

AssertionError [ERR_ASSERTION]: Task never defined: 
    at getFunction (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/undertaker/lib/helpers/normalizeArgs.js:15:5)
    at map (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/arr-map/index.js:20:14)
    at normalizeArgs (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/undertaker/lib/helpers/normalizeArgs.js:22:10)
    at Gulp.series (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/node_modules/undertaker/lib/series.js:13:14)
    at Object.<anonymous> (/Users/micklo/Desktop/AppsScriptProjects/AppsScriptAppName/gulpfile.js:4:24)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)

What am i doing wrong?

Some info:

OS: Mac Os (Mojave)

Gulp Versions -> CLI version: 2.1.0, Local version: 4.0.0

Node: v10.15.3

Clasp: 2.1.0

Upvotes: 3

Views: 1122

Answers (2)

Ravi Shankar
Ravi Shankar

Reputation: 31

   For re-write this gulpfile.js in gulp version 4.0 Please updated your 
   gulpfile.js according to your requirement. 

   this solution for assert.js:350 throw err; Bootstarp 4, SASS, gulp 4.

////////////////////////////////////////////////////////////////////////////////

    var gulp        = require('gulp');
    var browserSync = require('browser-sync').create();
    var sass        = require('gulp-sass');

    // Compile sass into CSS & auto-inject into browsers
    gulp.task('sass', function() {
        return gulp.src(['node_modules/bootstrap/scss/bootstrap.scss', 
        'src/scss/*.scss'])
            .pipe(sass())
            .pipe(gulp.dest("src/css"))
            .pipe(browserSync.stream());
    });

    // Move the javascript files into our /src/js folder
    gulp.task('js', function() {
        return gulp.src(['node_modules/bootstrap/dist/js/bootstrap.min.js', 
         'node_modules/jquery/dist/jquery.min.js', 
         'node_modules/popper.js/dist/umd/popper.min.js'])
            .pipe(gulp.dest("src/js"))
            .pipe(browserSync.stream());
    });

    // Static Server + watching scss/html files
    gulp.task('serve', gulp.series('sass', function() {

        browserSync.init({
            server: "./src"  
        });

        gulp.watch(['node_modules/bootstrap/scss/bootstrap.scss', 
         'src/scss/*.scss'], gulp.series('sass'));
        gulp.watch("src/*.html").on('change', browserSync.reload);
    }));

    gulp.task('default', gulp.parallel('js','serve'));

Upvotes: 0

Zwei
Zwei

Reputation: 1279

The quick fix to that particular error is that you have called gulp.series on an empty/non-existant task in your push task. gulp.series is expecting either a list of strings corresponding to tasks you've declared (such as push, watch, and default) or task functions.

Getting rid of the the '' task in the series will fix it:

gulp.task('push', gulp.series(function(){
    exec('clasp push')
}));

However you now have some other problems:

  1. None of your tasks have callbacks. Each Gulp task is asynchronous so you either have to use callbacks or return a stream/promise/event emitter/child process/observable (examples of which are located in the docs here). As an example:
gulp.task('push', function(done){
    exec('clasp push', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        done(err);
      });
});
  1. You're not passing in a function or series/parallel sequence to gulp.watch so it's not doing anything. If you're trying to run the push task whenever any .js or .html files are changed, you will want to change it to:
gulp.task('watch', function(done) {
    gulp.watch([
        '**/*.js',
        '**/*.html'
    ], gulp.series('push'));
    done();
});
  1. Your glob patterns have an extra space in the watch command before the file extension: '**/*.js' instead of '**/* .js'
  2. You likely want require("child_process").exec (with the extra .exec tagged on) to allow you to execute shell commands using an exec(command) syntax.
  3. You don't need to repeat the watch command when calling it in the default task:
gulp.task('default', gulp.series('push', 'watch'));
  1. You can remove a lot of the gulp.series calls to remove the <anonymous> task calls and simplify the tasks. Each task only needs one function and you should probably aim to use gulp.series and gulp.parallel with sets of named tasks.

Changing those points, the code should look something like:

const gulp = require('gulp');
const exec = require('child_process').exec;

gulp.task('push', function(done){
    exec('clasp push', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        done(err);
      });
});

gulp.task('watch', function(done) {
    gulp.watch([
        '**/*.js',
        '**/*.html'
    ], gulp.series('push'));
    done();
});

gulp.task('default', gulp.series('push', 'watch'));

You can rewrite this using the gulp v4 recommended pattern of exporting tasks:

const { series, watch } = require('gulp');
const { exec } = require('child_process');

function push(done) {
    exec('clasp push', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        done(err);
      });
}

function watchPush() {
    return watch(['**/*.js', '**/*.html'], push);
}

exports.push = push;
exports.default = exports.watch = series(push, watchPush);

Upvotes: 2

Related Questions