1

Using gulp 3.9.1

I am attempting to return a bunch of files and perform a task that requires a var to be passed between two pipes.

  1. I'm using node uuid to create a v3 UUID for each file path to ultimately end up with a uuid for each page. I'm grabbing the file path with gulp-print.
  2. I want to store that uuid value as a var. In the next pipe Im using gulp-inject-string to write it into the page during the build.

Help: Either I need help getting the file path inside the gulp-inject-string pipe or I need to pass the var between the two different pipes. If I globally set a var with a default value outside the src it gets passed easily to the pipe(inject).

Super simplified code below:

// test code
var gulp = require('gulp');
var print = require('gulp-print');
var inject = require('gulp-inject-string');
var reload = browserSync.reload;

const uuidv3 = require('uuid/v3');
var uuid;

gulp.task('uuid', function() {

    return gulp.src('**/*.html'])

        // create uuid
        .pipe(print(function(filepath) {
            uuid = uuidv3(filepath, uuidv3.URL);
            return "compiled: " + filepath + ' uuid: ' + uuid;
        }))

        // need to to add UUIDv3 to each page
        .pipe(inject.before('</head>', '<meta name="dc.identifier" content="' + uuid + '">'))
        .pipe(gulp.dest('/prod/./'))

        .pipe(reload({ stream: true }));
});

It's worth noting that I need a cross platform way to get the file path starting in the root of the project and including forward slashes. The gulp(print) does this perfectly starting at the root of the project and ignoring anything upstream from that point. The format of the path is important because it's one half of the equation in creating the uuid and the uuid's must match on Mac or PC platforms.

examples:

/index.html  
/dir1/file.html  
/dir1/dir2/dir3/file.html
Greg
  • 155
  • 11
  • Just declare a var before "return gulp.src...….", (or before the task altogether) , set it in the print pipe and refer to it later. If you are worried about correct slashes look at path.sep from node's path library (and path.join too). – Mark Jan 29 '18 at 20:17
  • I can't declare the var outside the gulp src (or before the task) because then I wouldn't be using the file path of the file(s) that's returned in the src. – Greg Jan 30 '18 at 06:24

2 Answers2

0
var gulp            = require('gulp');
var print           = require('gulp-print');
var inject          = require('gulp-inject-string');
const uuidv3        = require('uuid/v3');

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

// you can declare here
var uuid;

gulp.task('pages', function() {

    // or you can declare here
    var uuid;

return gulp.src('**/*.html')
    // bunch of stuff happens here involving templating/minifying
    // create uuid
    .pipe(print(function(filepath) { 

        // then set it here and use it further below
        // it will be available

        uuid = uuidv3(filepath, uuidv3.URL);

        return "compiled: " + filepath + ' uuid: ' + uuid;
    }))
    // need to to add UUIDv3 to each page
    //.pipe(inject.before('</head>', '<meta name="dc.identifier" content="' + uuid + '">\n'))

  .pipe(tap(function(file, t) {

    return t.through(inject.before('</head>', '<meta name="dc.identifier" content="' + uuid + '">\n');

   })

    .pipe(gulp.dest('/prod/./')) 
    .pipe(reload({stream:true}));    
});

You are just creating a variable at a higher scope that you can set and refer to later. If you need a bunch of them create an array with filepath as an index. But I would try it first as just a simple value.

Mark
  • 143,421
  • 24
  • 428
  • 436
  • I tried declaring an empty variable both above the task and just inside the task before the gulp.src as you have it in your example and I made sure I didn't declare it again inside the pipe(print) by removing the text "var" before the uuid and I keep getting a ReferenceError "udid is not defined" in terminal on the line in the code that starts with .pipe(inject.before.... no idea how to set a variable array I also tried this var uuid = []; //Define array pages //loop through all pages for (i = 0; i < (1000); i++) { uuid.push( i + ".tmpl"); //Add to array } – Greg Jan 30 '18 at 15:28
  • "udid" is not defined - do you mean "uuid" there? – Mark Jan 30 '18 at 16:43
  • It's in your original code too - I changed it in my code previously. In the inject pipe. – Mark Jan 30 '18 at 17:10
  • Bad code in original question a result of typing directly in web form on this site - my fault there. I have updated original question without typo. Still doesn't work, What about wrapping with gulp-foreach? – Greg Jan 30 '18 at 17:44
  • If I set the var uuid = "apples"; at the top I'll get a valid UUID returned in the console "uuid: b20be24d-3916-33c2-ab15-ff3446ed34d8" and "apples" returned in the injected HTML. – Greg Jan 30 '18 at 17:59
  • Is uuidv3() a synchronous function? – Mark Jan 30 '18 at 18:00
  • Have a look at https://stackoverflow.com/questions/22026389/passing-variables-between-pipes-in-gulp gulp-tap looks promising. I modified my answer above to show it. – Mark Jan 30 '18 at 18:19
0

I solved the problem. It was an amateur mistake. I returned the statement where the var was set so the var was essentially killed. Updated code that allows the var to pass through the pipes.

var gulp     = require('gulp');
var print    = require('gulp-print');
var replace  = require('gulp-replace');
const uuidv3 = require('uuid/v3');

var uuid;

gulp.task('build', function() {
    return gulp.src('**/*.html')
    // get a cross-platform filepath and create a uuid
    .pipe(print(function(filepath) {
        uuid = uuidv3(filepath, uuidv3.URL);
    }))
    // inject uuid
    .pipe(replace('dc.identifier" content=""', function() {
        return 'dc.identifier" content="' + uuid + '"';
    }))
    .pipe(gulp.dest('/prod/./'));
});

The var uuid passes through the pipes just fine now. This code creates a UUID based on a cross-platform file path and injects it into an empty dc.identifier meta tag.

Greg
  • 155
  • 11
  • Worth noting that you have to wrap those two pipes in a gulp-foreach because as the stream returns a bunch of files a UUID is created in one pipe but it may not inject the same var into the original file, Another file grabs it in the second pipe sometimes. The foreach makes it pass each page through one at a time. – Greg Feb 14 '18 at 02:45