In a Gulp task, how can I set a variable value in the first pipe and read it in the second pipe?

99封情书 提交于 2020-01-17 05:13:08

问题


I have a task with two piped statements. The second pipe relies on a global variable whose value is declared in the first pipe. But, I am not able to access the global variable from the second pipe. It seems like pipe 2 is starting before pipe 1 finishes.

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:


Problem:

You compute the value for the imageA1Width var in the tap() pipeline stage meaning the var is reset for every file moving through the stream.

However imageA1Width is evaluated only once (as part of the object literal that gets passed to responsive()) and before the stream has even been created. At that time imageA1Width is still undefined.

Solution:

What we need to do is compute a different width value for each file in the stream. Then for each file we need to call responsive() individually since each file will have a different width. We can do this using 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/'));
});


来源:https://stackoverflow.com/questions/36487551/in-a-gulp-task-how-can-i-set-a-variable-value-in-the-first-pipe-and-read-it-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!