Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running gulp task after loading file

I'm trying to copy, concatenate and minify specific javascript files to a dist bower_components directory using a manifest JSON file to keep things cleaner.

I'd like to run the concat and uglify in a separate task but the delay for the file to load means any dependent tasks run before it's finished.

// editorial tools gulp file
var gulp = require("gulp");

var path = require("path"),
argv = require("yargs").argv,
fs = require("fs"),
runSequence = require("run-sequence");

// load plugins
var $ = require("gulp-load-plugins")({ lazy: false });

gulp.task("other-task", ["read-manifest"], function () {
    // something else before read-manifest...
});

gulp.task("read-manifest", function () {

var cwd = process.cwd();

// vendor JS to compile (get manifest of files to bring in)
fs.readFile(cwd + "/src/bower_manifest.json", "utf-8", function (err, _data) {
    if (err) {
        console.log("Error: " + err);
        return;
    }

    // manifest string to JSON
    data = JSON.parse(_data);

    // copy bower files in manifest
    var fileList = data.fileUrls,
        loadOrder = data.loadOrder,
        filesToCopy = [];

    for ( var i = 0, len = loadOrder.length; i < len; i ++ ) {
        filesToCopy.push("./src/bower_components/" + fileList[loadOrder[i]]);
    }

    // add shared js
    filesToCopy.push("./src/javascripts/*.js");

    console.log(filesToCopy);

    // concat and uglify
    return gulp.src(filesToCopy)
        .pipe($.concat("shared.min.js"))
        // .pipe($.uglify())
        .pipe(gulp.dest("./dist/javascripts/"));

    $.util.log($.util.colors.green("JS combined and uglified"));
});
});

Console:

[gulp] Starting 'read-manifest'...
[gulp] Finished 'read-manifest' after 476 μs
[gulp] Starting 'other-task'...
[ './src/bower_components/jquery/jquery.min.js',
  './src/bower_components/aight/aight.min.js',
  './src/bower_components/d3/d3.min.js',
  './src/bower_components/aight/aight.d3.min.js',
  './src/javascripts/*.js' ]
[gulp] Finished 'other-task' after 15 ms
like image 749
Rich Avatar asked Dec 06 '22 01:12

Rich


2 Answers

As far as I can understand the main problem you have is that you are trying to use this task as a dependant of another task and that task starts before this task finishes.

To support async tasks you either need to return a promise, a stream or call a done callback. What you do now is to return a stream, but inside a callback. So the task function will not get a stream returned (as it is async). So a easier way to do this is to either use a promise or a callback..

Example with using the callback:

// note the "done" callback
gulp.task("read-manifest", function (done) {

    var cwd = process.cwd();

    // vendor JS to compile (get manifest of files to bring in)
    fs.readFile(cwd + "/src/bower_manifest.json", "utf-8", function (err, _data) {
         if (err) {
             console.log("Error: " + err);
             return;
         }
         // ... etc ...
        gulp.src(filesToCopy)
            .pipe($.concat("shared.min.js"))
            // .pipe($.uglify())
            .pipe(gulp.dest("./dist/javascripts/"))

            // when stream ends, call callback
            .on('end', done); 
    });
});

Or you can use a promise like this:

var Q = require('q');

gulp.task("read-manifest", function () {
    var deferred = Q.defer();
    var cwd = process.cwd();

    // vendor JS to compile (get manifest of files to bring in)
    fs.readFile(cwd + "/src/bower_manifest.json", "utf-8", function (err, _data) {
         if (err) {
             console.log("Error: " + err);
             return;
         }
         // ... etc ...
        gulp.src(filesToCopy)
            .pipe($.concat("shared.min.js"))
            // .pipe($.uglify())
            .pipe(gulp.dest("./dist/javascripts/"))

            // when stream ends, call callback
            .on('end', function () {
                 deferred.resolve();
            }); 
    });
    return deferred.promise;
});

Does that make any sense? This way the dependants know when this task is done. Read more about async support in the documentation

like image 73
mikaelb Avatar answered Dec 08 '22 15:12

mikaelb


// gulpfile.js
var gulp = require('gulp');
var Promise = require('promise');

gulp.task('lazy-load-task', function(){
    var LazyLoad = require('your-lazy-load-js');
    return new Promise(function(resolve, reject){
        // define your lazy task depends on LazyLoad
        gulp.task('lazy-task', function(){
            // TODO: do your logic with LazyLoad here
            resolve(0);
            return Promise.resolve(0); // optional
        });
        // execute it
        gulp.start('lazy-task');
    });
});

gulp.task('default', ['lazy-load-task']);
like image 32
Bear Vast Avatar answered Dec 08 '22 15:12

Bear Vast