Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run code after gulp task done with all files

So I have been trying out Gulp to see how it compares to Grunt as far as speed and I am pretty impressed with the results but I have one thing I don't know how to do in Gulp.

So I have this gulp task to minify HTML:

gulp.task('html-minify', function() {
  var files = [
    relativePaths.webPath + '/*.html',
    relativePaths.webPath + '/components/**/*.html',
    relativePaths.webPath + '/' + relativePaths.appPath + '/components/**/*.html'
  ];

  var changedFiles = buildMetaData.getChangedFiles(files);

  //TODO: needs to execute only after successful run of the task
  buildMetaData.addBuildMetaDataFiles(changedFiles);
  buildMetaData.writeFile();
  return gulp.src(changedFiles, {
      base: relativePaths.webPath
    })
    .pipe(filelog())
    .pipe(minifyHtml({
      empty: true,
      quotes: true,
      conditionals: true,
      comments: true
    }))
    .pipe(gulp.dest(relativePaths.webPath + '/' + relativePaths.appPath +  '/' + relativePaths.buildPath));
});

The buildMetaData object has custom functionality that I need and why I can't use plugins like gulp-changed. What I am trying to figure out is how (if possible) to run a block of code after the minify is done process all files and it run successfully. Is something like this possible with gulp?

like image 647
ryanzec Avatar asked Jul 06 '14 20:07

ryanzec


People also ask

What is Gulp Gulpfile?

Gulpfile explained A gulpfile is a file in your project directory titled gulpfile. js (or capitalized as Gulpfile. js , like Makefile), that automatically loads when you run the gulp command.

What is Gulp watch command?

Advertisements. The Watch method is used to monitor your source files. When any changes to the source file is made, the watch will run an appropriate task. You can use the 'default' task to watch for changes to HTML, CSS, and JavaScript files.

How do you define a task in Gulp?

To have your tasks execute in order, use the series() method. For tasks to run at maximum concurrency, combine them with the parallel() method. Tasks are composed immediately when either series() or parallel() is called. This allows variation in the composition instead of conditional behavior inside individual tasks.


3 Answers

You could just make a task which depends on html-minify:

gulp.task('other-task', ['html-minify'], function() {
  //stuff
});

You could also listen for the stream end event inside the html-minify task:

gulp.task('html-minify', function(done) {
  var files = [
    relativePaths.webPath + '/*.html',
    relativePaths.webPath + '/components/**/*.html',
    relativePaths.webPath + '/' + relativePaths.appPath + '/components/**/*.html'
  ];

  var changedFiles = buildMetaData.getChangedFiles(files);

  //TODO: needs to execute only after successful run of the task
  buildMetaData.addBuildMetaDataFiles(changedFiles);
  buildMetaData.writeFile();
  var stream = gulp.src(changedFiles, {
      base: relativePaths.webPath
    })
    .pipe(filelog())
    .pipe(minifyHtml({
      empty: true,
      quotes: true,
      conditionals: true,
      comments: true
    }))
    .pipe(gulp.dest(relativePaths.webPath + '/' + relativePaths.appPath +  '/' + relativePaths.buildPath));

  stream.on('end', function() {
    //run some code here
    done();
  });
  stream.on('error', function(err) {
    done(err);
  });
});
like image 121
Ben Avatar answered Oct 17 '22 21:10

Ben


You can also merge two streams with with event-stream. This example takes input from the command line with yargs, builds a config and then merges the two:

var enviroment = argv.env || 'development';
gulp('build', function () {
    var config = gulp.src('config/' + enviroment + '.json')
      .on('end', function() { gutil.log(warn('Configured ' + enviroment + ' enviroment.')); })
      .pipe(ngConstant({name: 'app.config'}));
    var scripts = gulp.src('js/*');
    return es.merge(config, scripts)
      .pipe(concat('app.js'))
      .pipe(gulp.dest('app/dist'))
      .on('error', function() { });
  });

As well as the standard before tasks, you can also wait for a previous task to complete. This is useful when you need to pass arguments to the before task (which gulp does not currently support):

var tasks = {
  before: function(arg){
    // do stuff
  },
  build: function() { 
    tasks.before(arg).on('end', function(){ console.log('do stuff') });
  }
};

gulp('build', tasks.build);
like image 28
Rimian Avatar answered Oct 17 '22 19:10

Rimian


GULP V3

Using dependency tasks:

gulp.task('qr-task', ['md-task', 'js-task'], function() {
  gulp.src(src + '/*.qr')
    .pipe(plugin())
    .pipe(gulp.dest(dist));
});

Although main task starts after all of dependent tasks but they (dependent tasks) will run in parallel (all at once), so don't assume that the tasks will start/finish in order (md and js run in parallel before qr).

If you want exact order for several tasks and don't want to split them you can use async & await to achieve this:

function Async(p) {
   return new Promise((res, rej) => p.on('error', err => rej(err)).on('end', () => res()));
}

gulp.task('task', async () => {

  await Async(gulp.src(src + '/*.md')
      .pipe(plugin())
      .pipe(gulp.dest(dist)));

  await Async(gulp.src(src + '/*.js')
      .pipe(plugin())
      .pipe(gulp.dest(dist)));

  await Async(gulp.src(src + '/*.qr')
      .pipe(plugin())
      .pipe(gulp.dest(dist)));
});

GULP V4

in gulp 4 the old dependency pattern is removed and you will get this error:

AssertionError [ERR_ASSERTION]: Task function must be specified

instead you must use gulp.parallel and gulp.series (which provides correct execution of tasks):

gulp.task('qr-task', gulp.series('md-task', 'js-task', function(done) {
  gulp.src(src + '/*.qr')
    .pipe(plugin())
    .pipe(gulp.dest(dist));
  done();
}));

for more detail visit https://github.com/gulpjs/gulp/blob/4.0/docs/API.md

like image 3
Ali Avatar answered Oct 17 '22 19:10

Ali