gulp-community / gulp-concat

Streaming concat middleware for gulp
MIT License
792 stars 126 forks source link

Possible to fail lazily? #130

Closed fvsch closed 7 years ago

fvsch commented 7 years ago

Currently if one one uses gulp-concat like this:

const concat = require('gulp-concat')
const badConcat = concat()

it throws because the file argument is falsy. Same for values such as false and the empty string.

Maybe I’m talking nonsense here, but would it be possible for gulp-concat to fail not on initialization, but when it is first written to? (Note: I know very little about Node.js streams or how gulp uses them.)

return gulp.src(…)
  .pipe( transformContent() )
  // throws when config.concatFilename is falsy
  .pipe( gulpIf(config.concatFilename, concat(config.concatFilename)) )

It took me a while to figure out that, even though the gulp-concat stream may not be used, it is still built. The workaround I found was:

const schrodingersConcat = gulpIf(config.concatFilename,
  concat(config.concatFilename || 'nope'))

return gulp.src(…)
  .pipe( transformContent() )
  .pipe( schrodingersConcat )

If a change in gulp-concat would not be desirable, maybe this issue and a workaround could be documented in the README?

yocontra commented 7 years ago

Why are you passing these values into it? Need more context.

fvsch commented 7 years ago

I’m working on a Sass+Autoprefixer gulp task (and a corresponding LESS+Autoprefixer one with the same config options). I would like the same task to output either a bunch of files, or the same data but concatenated to one file, depending on user options.

// Resolve some user options for Sass and Autoprefixer
// ...
// Should we write several files or concatenate?
const dest = path.parse(userConfig.dest) // e.g. 'dist/css', or 'dist/app.css' 
const destFile = dest.ext === '.css' ? dest.base : false // e.g. false or 'app.css'
const destDir = destFile ? dest.dir : userConfig.dest

return gulp.src( userConfig.src ) // e.g. 'styles/*.scss'
    .pipe( sourcemaps.init() )
    .pipe( sass(sassOptions) )
    .pipe( autoprefixer(prefixOptions) )
    .pipe( gulpIf(destFile, concat(destFile)) )
    .pipe( sourcemaps.write('.') )
    .pipe( gulp.dest(destDir) )

Maybe using the destination file/folder name as a way to decide "should we concat or not?" is a bit too "magic", but even if I provided a boolean userConfig.concat option the issue with gulp-concat would remain the same: I’d have to create the stream with a bogus filename.

yocontra commented 7 years ago

You can pipe however you want, so don't pipe or construct concat based on whatever conditions you need.

const stream = gulp.src(whatever)

if (something) stream = stream.pipe(someotherthing())

return stream