hughsk / vinyl-map

Map vinyl files' contents as strings
MIT License
36 stars 7 forks source link

Gulp: all files processed by stream are not written to filesystem #7

Open benmosher opened 9 years ago

benmosher commented 9 years ago

See gulpjs/gulp#832, but the short story is: all of my files appear to be processed, but they are not all written out by gulp.dest at the end of my pipeline.

Here is my Gulp task, so you can properly shame me if it's something simple:

var JSX_OPTIONS = {
    harmony: true };
gulp.task('scripts:jsx', function () {
    return gulp.src(source.scripts.jsx)
        .pipe(map(function (source, filePath) {
            try {
                return reactTools.transform(source.toString(), JSX_OPTIONS);
            }
            catch (err) {
                err.filePath = filePath;
                util.log(err);
            }
        }))
        .pipe(gulp.dest(dest.scripts.jsx));
});
Antonimo commented 9 years ago

i have the workaround if ur interested. basicly i made a copy of vinyl-map, fixed it and include it as such.

https://github.com/hughsk/vinyl-map/pull/6

vinyl-map.js:

var through = require('through2')
var from    = require('new-from')
var bl      = require('bl')

module.exports = map

function map(fn) {
  var done = null
  var pending = 0
  var stream

  return stream = through.obj(write, flush)

  function write(file, _, next) {
    if (typeof file !== 'object') return
    if (!('contents' in file)) return push(file, next)

    if (file.isNull()) return push(file, next)
    if (file.isBuffer()) return map(file, next)

    // should be a stream by
    // this point...
    pending++
    file.contents.pipe(bl(function(err, result) {
      if (err) return stream.emit('error', err)
      map(file, next, result)
      check(--pending)
    }))
  }

  function map(file, next, contents) {
    file = file.clone()
    contents = arguments.length < 3
      ? file.contents
      : contents

    try {
      var mapped = fn(contents, file.path)
    } catch(err) {
      return stream.emit('error', err)
    }

    if (mapped === undefined) mapped = contents
    if (file.isBuffer()) file.contents = new Buffer(mapped)
    if (file.isStream()) file.contents = from([mapped])

    push(file, next)
  }

  function push(file, next) {
    stream.push(file)
    next()
  }

  function flush(cb) {
    check(done = cb)
  }

  function check() {
    if (!pending && done) {
      done();
    }
  }
}
henrify commented 9 years ago

I just wasted all afternoon hunting down non-deterministic build problems, and finally tracked it down to this issue of vinyl-map.

Yes yes, I know this is an open source project and on best effort basis, but honestly, this plugin fails catastrophically (and silently) on it's primary purpose -- doesn't frigging write it's output -- and then you leave the issue open for half a year+.

If you don't fix issues that are this serious in timely manner, at least formally discontinue your plugin so that you don't waste other peoples time.

jhannwong commented 9 years ago

@henrify I have gotten it to work by listening on end event. See gulpjs/gulp#1254.

@Antonimo @benmosher Is this still an open issue? Is the end event workaround adequate?