在Gulp任务中,如何在第一个管道中设置变量值并在第二个管道中读取它?

时间:2016-04-07 21:28:15

标签: node.js gulp

我有两个管道语句的任务。第二个管道依赖于一个全局变量,其值在第一个管道中声明。但是,我无法从第二个管道访问全局变量。似乎管道2在管道1完成之前就开始了。

var responsive = require('gulp-responsive');
var tap = require('gulp-tap');

// global variables for image-generator task
var imageA1Width = 0;
var imageA1Height = 0;

// extracts width and height from image path
function getDimensionsFromPath(path) {
    // example image: banner-fooBar-$a1-1000x901.jpg
    var path = path || '';
    var dimensionsString = '';
    var width = 0;
    var height = 0;
    var re = /[^-]*$/;
    dimensionsString = path.match(re)[0];
    dimensionsString = dimensionsString.replace('.jpg', '');
    dimensionsString = dimensionsString.replace('.png', '');
    dimensionsString = dimensionsString.replace('.webp', '');
    dimensionsString = dimensionsString.replace('.gif', '');
    var dimensionsArr = dimensionsString.split('x');
    width = parseInt(dimensionsArr[0], 10);
    height = parseInt(dimensionsArr[1], 10);
    var obj = {
        width: width,
        height: height
    };
    return obj;
}

gulp.task('image-generator', function () {
    var imageKeyPattern = /-\$a1.*$/; // example image: banner-fooBar-$a1-1000x901.jpg
    return gulp.src('images/**/*$a1*.*')
        .pipe(tap(function (file, t) {
            var imageA1Path = file.path;
            // global variables
            imageA1Width = getDimensionsFromPath(imageA1Path).width;
            imageA1Height = getDimensionsFromPath(imageA1Path).height;
        }))
        .pipe(responsive({
            '**/*$a1*.*': [{
                width: imageA1Width * 2, // NaN
                skipOnEnlargement: true,
                rename: function (opt) {
                    opt.basename = opt.basename.replace(imageKeyPattern, '-extralarge@2x');
                    opt.dirname = '';
                    return opt;
                }
            },
            ]
        }))
        .pipe(gulp.dest('imagesGenerated/'));
});

1 个答案:

答案 0 :(得分:1)

<强>问题:

您在imageA1Width管道阶段中计算tap() var的值,这意味着会为每个文件移动流重置var。

但是imageA1Width仅评估一次(作为传递给responsive()的对象文字的一部分)并且甚至在创建了流之前。那时imageA1Width仍未定义。

<强>解决方案:

我们需要做的是为流中的每个file计算不同的宽度值。然后,对于每个file,我们需要单独调用responsive(),因为每个file将具有不同的宽度。我们可以使用gulp-foreach

执行此操作
var foreach = require('gulp-foreach');

gulp.task('image-generator', function () {
  var imageKeyPattern = /-\$a1.*$/;
  return gulp.src('images/**/*$a1*.*')
    .pipe(foreach(function(stream, file) {
       var size = getDimensionsFromPath(file.path);
       return stream
        .pipe(responsive({
           '**/*$a1*.*': [{
             width: size.width * 2,
             skipOnEnlargement: true,
             rename: function (opt) {
               opt.basename = opt.basename.replace(imageKeyPattern, 
                                                   '-extralarge@2x');
               opt.dirname = '';
               return opt;
             }
           }]
         }));
    }))
    .pipe(gulp.dest('imagesGenerated/'));
});