如何使用Gulp.js将流保存到多个目标位置?

65
const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const source = require('vinyl-source-stream');
const browserify = require('browserify');

gulp.task('build', () =>
  browserify('./src/app.js').bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./build'))       // OK. app.js is saved.
    .pipe($.rename('app.min.js'))
    .pipe($.streamify($.uglify())
    .pipe(gulp.dest('./build'))       // Fail. app.min.js is not saved.
);

当文件内容为流时,将其导向多个目的地是目前不支持的。有什么解决此问题的方法吗?

5个回答

40

我遇到了类似的问题,希望在lint、uglify和minify任务之后将gulp源代码复制到多个位置。我最终解决了这个问题如下:

gulp.task('script', function() {
  return gulp.src(jsFilesSrc)
    // lint command
    // uglify and minify commands
    .pipe(concat('all.min.js'))
    .pipe(gulp.dest('build/js')) // <- Destination to one location
    .pipe(gulp.dest('../../target/build/js')) // <- Destination to another location
});

37

目前在使用文件内容作为流时,每个目标需要使用两个流。这个问题可能会在未来得到解决。

var gulp       = require('gulp');
var rename     = require('gulp-rename');
var streamify  = require('gulp-streamify');
var uglify     = require('gulp-uglify');
var source     = require('vinyl-source-stream');
var browserify = require('browserify');
var es         = require('event-stream');

gulp.task('scripts', function () {
    var normal = browserify('./src/index.js').bundle()
        .pipe(source('bundle.js'))
        .pipe(gulp.dest('./dist'));

    var min = browserify('./src/index.js').bundle()
        .pipe(rename('bundle.min.js'))
        .pipe(streamify(uglify())
        .pipe(gulp.dest('./dist'));

    return es.concat(normal, min);
});

编辑:这个错误现在已经在gulp中修复了。您原始帖子中的代码应该可以正常工作。



5
我们能不能保存bundle()的输出, var bundle = browserify('./src/index.js').bundle(); 然后将其馈送到两个不同的“管道”中?例如 bundle.pipe(source('bundle.js')).pipe(gulp.dest('./dist'));bundle.pipe(rename('bundle.min.js')).pipe(streamify(uglify()) .pipe(gulp.dest('./dist')); 这样,bundle只运行一次,我们就可以两次使用输出。 - AntouanK
5
从哪个版本的gulp开始修复了这个bug? - Alireza Mirian
@AlirezaMirian +1,想知道是哪个版本修复了这个问题。 - anjunatl

5
我认为这种方法更简单。你有两个目标,但在使用缩小插件之前,你需要将一个路径放到普通文件中,然后再按照你想要缩小的文件的路径放置缩小插件。
例如:
gulp.task('styles', function() {

    return gulp.src('scss/main.scss')
    .pipe(sass())
    .pipe(gulp.dest('css')) // Dev normal CSS
    .pipe(minifycss())
    .pipe(gulp.dest('public_html/css')); // Live Minify CSS

});

5

如果需要将更新广播到多个目标,可以将 gulp.dest 命令循环执行以覆盖多个目标。

var gulp = require('gulp');

var source = './**/*';

var destinations = [
    '../foo/dest1',
    '../bar/dest2'
];

gulp.task('watch', function() {
    gulp.watch(source, ['sync']);
});

gulp.task('sync', function (cb) {
    var pipeLine = gulp.src(source);

    destinations.forEach(function (d) {
        pipeLine = pipeLine.pipe(gulp.dest(d));
    });

    return pipeLine;
});

0

我在使用Gulp时遇到了很多相同的问题,对于多个任务管道到多个目标似乎很困难或者潜在地不可能。此外,为一个任务设置多个流似乎效率低下,但我想这是目前的解决方案。

对于我的当前项目,我需要将多个捆绑包与各种页面相关联。修改Gulp Starter是我的解决方案。

https://github.com/greypants/gulp-starter

browserify/watchify任务:

https://github.com/dtothefp/gulp-assemble-browserify/blob/master/gulp/tasks/browserify.js

我在glob模块的回调函数中使用了forEach循环:
gulp.task('browserify', function() {

  var bundleMethod = global.isWatching ? watchify : browserify;

  var bundle = function(filePath, index) {
    var splitPath = filePath.split('/');
    var bundler = bundleMethod({
      // Specify the entry point of your app
      entries: [filePath],
      // Add file extentions to make optional in your requires
      extensions: ['.coffee', '.hbs', '.html'],
      // Enable source maps!
      debug: true
    });

    if( index === 0 ) {
      // Log when bundling starts
      bundleLogger.start();
    }

    bundler
      .transform(partialify)
      //.transform(stringify(['.html']))
      .bundle()
      // Report compile errors
      .on('error', handleErrors)
      // Use vinyl-source-stream to make the
      // stream gulp compatible. Specifiy the
      // desired output filename here.
      .pipe(source( splitPath[splitPath.length - 1] ))
      // Specify the output destination
      .pipe(gulp.dest('./build/js/pages'));

    if( index === (files.length - 1) ) {
      // Log when bundling completes!
      bundler.on('end', bundleLogger.end);
    }

    if(global.isWatching) {
      // Rebundle with watchify on changes.
      bundler.on('update', function(changedFiles) {
        // Passes an array of changed file paths
        changedFiles.forEach(function(filePath, index) {
          bundle(filePath, index);
        });
      });
    }
  }

  // Use globbing to create multiple bundles
  var files = glob('src/js/pages/*.js', function(err, files) {
    files.forEach(function(file, index) {
      bundle(process.cwd() + '/' + file, index);
    })
  });

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接