В задаче 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 ответ

Решение

Проблема:

Вы вычисляете значение для imageA1Width вар в tap() этап конвейера, означающий, что переменная сбрасывается для каждого файла, проходящего через поток.

тем не мение 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/'));
});
Другие вопросы по тегам