Frank Spin
Frank Spin

Reputation: 1483

Gulp Task - Pass var to next pipe

I have the following gulp task

// global criticalCSS
criticalCSS = "";

// Generate & Inline Critical-path CSS
gulp.task('optimize:critical', ['styles'], function() {
  critical.generate({
    base: config.critical.base,
    src: 'index.html',
    css: config.critical.css
    }, function (err, output) {
    // You now have critical-path CSS
      console.log(output);
      criticalCSS = output;
    });
    return gulp.src(config.critical.base + '/*.html')
    .pipe(plumber({
      errorHandler: onError
    }))
    .pipe(
      htmlreplace({
        'criticalCss': '<style>' + criticalCSS + '</style>',
      })
    )
    .pipe(vinylPaths(del))
    .pipe(gulp.dest(config.critical.base));
});

I expected that criticalCSS was globally containing the output of critical.generate. The console.log displays the output properly. But in

'criticalCss': '<style>' + criticalCSS + '</style>',

criticalCSS returns a empty string.

How can i solve this issue?

Upvotes: 1

Views: 257

Answers (1)

pieceOpiland
pieceOpiland

Reputation: 359

Just a shot in the dark, but it looks like the initial critical.generate call is being run asynchronously, and the criticalCSS variable isn't guaranteed to be properly initialized.

To ensure that the criticalCSS variable is initialized when you proceed to the gulp stream portion of this task, you can utilize the promise syntax of the critical plugin found at: https://www.npmjs.com/package/critical

However, you still need to let gulp know when the task has completed... You can utilize a callback method in conjunction with the stream events shown at: Run code after gulp task done with all files to let gulp know when the task has completed (and if any errors have occurred):

gulp.task('optimize:critical', ['styles'], function(done) {
  critical.generate({
    base: config.critical.base,
    src: 'index.html',
    css: config.critical.css})
  // Promise syntax that will run after critical has finished.
  .then(function (output) {
      // You now have critical-path CSS
      console.log(output);
      // criticalCSS = output;
      var stream = gulp.src(config.critical.base + '/*.html')
      .pipe(plumber({
        errorHandler: onError
      }))
      .pipe(
        htmlreplace({
          'criticalCss': '<style>' + output + '</style>',
        })
      )
      .pipe(vinylPaths(del))
      .pipe(gulp.dest(config.critical.base));
      stream.on('end', function() {
        done();
      });
      stream.on('error', function(err) {
        done(err);
      });
  // Error on the initial critical call
  }).error(function(err){
    done(err);
  });
});

In this version of the task, you shouldn't even need the criticalCSS variable.

Upvotes: 2

Related Questions