Gulp 管道中未处理的流错误

Gulp Unhandled stream error in pipe

我一直在使用一个 gulpfile,我现在对其进行了修改以尝试将源映射添加到我编译的 css 和缩小的 css 文件中。

我在文件中有以下任务:

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));
});

但是,在尝试编译时,出现以下错误:

stream.js:74
  throw er; // Unhandled stream error in pipe.

是源映射文件导致了问题。

当您执行 sourcemaps.write('.') 时,您会向流中发送一个 .map 文件。这意味着您的流中现在有两个文件:一个 CSS 文件和一个 sourcemaps 文件。

当 CSS 文件达到 cssnano() 时,它会被缩小。但是,当 sourcemaps 文件到达 cssnano() 时,就会发生错误。 cssnano() 尝试将文件解析为 CSS,但由于 sourcemaps 文件不是有效的 CSS 文件,因此失败并且 cssnano() 抛出。

在使用 gulp.dest() 将源映射文件持久化到磁盘后,您必须从流中删除它。您可以为此使用 gulp-filter 插件:

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));
});

在上面的 filter('**/*.css') 中只让 CSS 文件通过,而不是 sourcemaps 文件,这解决了问题。

我还在结尾处添加了第二个 sourcemaps.write('.'),因为您可能需要缩小和未缩小的 CSS 文件的源映射。

如果您的 运行 进入管道错误,我发现 this 非常有帮助

/**
 * 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);
    }
  }
}

如果你用 wrapPipe 包装任务函数并像上面的例子一样在所有管道上放置 .on(error, error) 方法,它将大量捕获错误并指出到问题文件,通常是行号。不需要古蒂尔。