4

I have a gulp script to manipulate a master html file and rename it into several name based on an array. here's the script.

    gulp.task('default', function () {
      var data = ['name1','name2'];
      for(var name in data){              
         gulp.src('src/master.html')
           .pipe(*dosomething...*)
           .pipe(rename(function(path) {
              path.basename = name;
              path.extname = '.html';
          }))
         .pipe(gulp.dest('dist'));
      }
    });

But only the name2.html is generated. Can anyone tell me what's wrong with my code.

Chito Cheng
  • 540
  • 2
  • 9
  • 25

2 Answers2

2

Don't make functions within a loop.

Your loop creates multiple functions that you pass to rename. Each of those functions refers to the same variable name. However those functions aren't executed immediately, but only after all of them have been created. That means all your functions refer to the last value that name had in the loop.

You need to create multiple name variables by replacing your for loop with a looping construct that creates a new function scope for each value, e.g. Array.forEach.

You are also creating multiple streams in your loop. You should return those streams after merging them with merge-stream so gulp can determine when your task has finished.

var gulp = require('gulp');
var rename = require('gulp-rename');
var merge = require('merge-stream');

gulp.task('default', function () {
  var data = ['name1','name2'];
  var streams = [];
  data.forEach(function(name) {
    var stream = gulp.src('src/master.html')
      .pipe(rename(function(path) {
        path.basename = name;
        path.extname = '.html';
      }))
      .pipe(gulp.dest('dist'));
    streams.push(stream);
  });
  return merge(streams);
});
Community
  • 1
  • 1
Sven Schoenung
  • 30,224
  • 8
  • 65
  • 70
  • It works. Thanks. By the way, what if data is a json object instead of array. forEach isn't available for object – Chito Cheng May 05 '16 at 08:36
  • [`Object.keys()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) returns an array of the object's keys, which let's you use `.forEach()` again: `Object.keys(jsonObject).forEach(function(key) {` – Sven Schoenung May 05 '16 at 08:56
0

for ... in is intended for looping through the keys of an object. For an array, the keys are the index values (0 and 1), so I'm surprised name2.html is being generated at all - perhaps it was already there from a previous run.

Either change to an indexed for loop for (var i = 0; i < data.length; i++) { ... or get the name from the array using path.basename = data[name];

Kable
  • 1,035
  • 8
  • 18