5

I have been using a gulpfile which, I have now modified to try and add sourcemaps to my compiled css and minified css files.

I have the following task in the file:

gulp.task('sass', function () {
return gulp.src('./src/sass/zebra.scss')

    .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer({
            browsers: autoprefixrBrowsers,
            cascade: false
        }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(destination))
    .pipe(cssnano())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(gulp.dest(destination));
});

However, when trying to compile, I get the following error:

stream.js:74
  throw er; // Unhandled stream error in pipe.
Sam Willis
  • 4,001
  • 7
  • 40
  • 59

2 Answers2

2

It's the sourcemap file that's causing the problem.

When you do sourcemaps.write('.') you emit a .map file into the stream. That means you now have two files in your stream: a CSS file and a sourcemaps file.

When the CSS file reaches cssnano() it gets minified. However when the sourcemaps file reaches cssnano() that's when the error happens. cssnano() tries to parse the file as CSS, but since sourcemaps files aren't valid CSS files, this fails and cssnano() throws up.

You have to remove the sourcemaps file from your stream after you have persisted it to disk with gulp.dest(). You can use the gulp-filter plugin for this:

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

gulp.task('sass', function () {
   return gulp.src('./src/sass/zebra.scss')

    .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer({
            browsers: autoprefixrBrowsers,
            cascade: false
        }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(destination))
    .pipe(filter('**/*.css'))
    .pipe(cssnano())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(destination));
});

In the above filter('**/*.css') only lets the CSS file through, not the sourcemaps file, which fixes the problem.

I have also added a second sourcemaps.write('.') right before the end since you probably want sourcemaps for both the minified and unminified CSS file.

Sven Schoenung
  • 30,224
  • 8
  • 65
  • 70
2

If your running into pipeline errors, I found this to be very helpful

/**
 * Wrap gulp streams into fail-safe function for better error reporting
 * Usage:
 * gulp.task('less', wrapPipe(function(success, error) {
 *   return gulp.src('less/*.less')
 *    .pipe(less().on('error', error))
 *    .pipe(autoprefixer().on('error', error))
 *    .pipe(minifyCss().on('error', error))
 *    .pipe(gulp.dest('app/css'));
 * }));
 */
function wrapPipe(taskFn) {
  return function(done) {
    var onSuccess = function() {
      done();
    };
    var onError = function(err) {
      done(err);
    }
    var outStream = taskFn(onSuccess, onError);
    if(outStream && typeof outStream.on === 'function') {
      outStream.on('end', onSuccess);
    }
  }
}

If you wrap the task function with wrapPipe and put the .on(error, error) method on all your pipes like in the example above, it will copiously catch the error and point to the problem file, and line# generally. No gutil needed.

blamb
  • 4,220
  • 4
  • 32
  • 50