Gulpjs将两个任务合并为一个任务

60

我目前有两个任务,都是用来编译Sass文件的。我仍然希望将这两个目录合并成单独的文件,但如果我可以创建一个“Sass”任务来负责所有Sass编译,那么这将更易于维护。

// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(contcat('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(contcat('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

更新:

我尝试过这个:

// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = function() {
    return gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  var site = function() {
    return gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  return Promise.all([bootstrap, site]);
});

但现在似乎两个文件都没有被编译。有什么建议可以告诉我我错在哪里吗?

11个回答

69

我认为做这件事情的正确方式是使用任务依赖。

在gulp中,你可以定义需要在给定任务之前运行的任务。

例如:

gulp.task('scripts', ['clean'], function () {
    // gulp.src( ...
});

在终端中执行gulp scripts命令时,会在运行scripts任务之前先运行clean任务。

在您的示例中,我会将两个单独的SASS任务作为一个公共SASS任务的依赖项。类似这样:

// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(contact('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(contact('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('sass', ['bootstrap-sass', 'site-sass']);

你可以在Gulp配方部分了解有关任务依赖的更多信息:https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md


3
对于那些在2019年左右遇到此问题的人:这种方法在Gulp 4中无效。请查看其他使用“parallel”和/或“series”的答案。 - ACJ

35

它有效。

var task1 = gulp.src(...)...
var task2 = gulp.src(...)...
return [task1, task2];

2
太好了,这绝对是最简单的解决方案,而且非常顺利。 - Stefan Walther
2
这不返回一个流。这个任务不能作为依赖项。 - pmiguelpinto

23

解决方案1:

gulp.task('sass', function() {
  gulp.start('bootstrap-sass', 'site-sass');
})

gulp.start并行运行任务,并且是异步的,这意味着'bootstrap-sass'可能在'site-sass'之前完成。但不建议使用它,因为

故意未记录gulp.start,因为它可能导致复杂的构建文件,我们不希望人们使用它

参见https://github.com/gulpjs/gulp/issues/426

解决方案2:

var runSequence = require('run-sequence');
gulp.task('sass', function (cb) {
  runSequence(['bootstrap-sass', 'site-sass'], cb);
});

run-sequence 是一个 gulp 插件。

按指定顺序运行一系列 gulp 任务。该函数旨在解决您已定义运行顺序但选择不使用依赖项的情况。

runSequence(['bootstrap-sass', 'site-sass'], cb);

这行代码并行运行了'boostrap-sass'和'site-sass'两个任务。如果您想要串行运行任务,可以

runSequence('bootstrap-sass', 'site-sass', cb);

你能解释一下你的答案吗?仅有代码的回答通常不被接受,因为它们并不能帮助其他人理解如何在未来独立解决问题。 - Wai Ha Lee
“推荐”在后Windows XP时代是一个被滥用的词。 - Ярослав Рахматуллин
@ЯрославРахматуллин 你能解释一下吗? - gzc
这是一个主观的评论;“推荐”有时用于指代傻瓜式的选择,我对此感到冒犯。其他时候,它被用来指向对提问者有益的选择(而不是被推荐的人)-例如,在安装向导中安装一些恶意软件(推荐)。在这个答案中,它是傻瓜式的选择。对于两个独立的任务来说,它是完全无关的,推荐对于除了非常特定的saas1和sass2用例之外的任何其他情况都是无用的。在我看来,理解事物比遵循建议更好。 - Ярослав Рахматуллин
@ЯрославРахматуллин 我使用“推荐”一词来表示建议或建议。我已经添加了一些解释,为什么不推荐使用。 - gzc

18

使用Gulp4,您可以使用:

  • gulp.series用于顺序执行任务
  • gulp.parallel用于并行执行任务

    gulp.task('default', gulp.series('MyTask001', 'MyTask002'));
    gulp.task('default', gulp.parallel('MyTask001', 'MyTask002'));

此处有相关文章
您不再需要run-sequence插件
您需要安装: npm install -D gulp@next


6
Gulp 4 版本 中,我们有 parallel,因此您可以执行以下操作:
// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(concat('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(concat('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('sass', gulp.parallel('bootstrap-sass', 'site-sass')); // Combine

你也可以将其作为一个单独的任务进行编写:

gulp.task('sass', gulp.parallel(
  function() {
      return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
        .pipe(sass())
        .pipe(concat('bootstrap.css'))
        .pipe(gulp.dest('./public/dist/css'));
  },
  function() {
      return gulp.src('./public/app/scss/*.scss')
        .pipe(sass())
        .pipe(concat('site.css'))
        .pipe(gulp.dest('./public/dist/css'));
  }));

我更喜欢第一种方法,因为它更容易维护。


5

我刚刚发现了一个叫做gulp-all的gulp插件并尝试使用。它很容易使用。

https://www.npmjs.com/package/gulp-all

该包的文档说:

var all = require('gulp-all')

var styl_dir = 'path/to/styles/dir'
var js_dir   = 'path/to/scripts/dir'

function build() {
    return all(
        gulp.src(styl_dir + '/**/*')
            // build Styles 
            .pipe(gulp.dest('dist_dir')),
        gulp.src(js_dir + '/**/*')
            // build Scripts 
            .pipe(gulp.dest('dist_dir'))
    )
}

gulp.task('build', build);

also you can put subtasks in an array:

var scriptBundles = [/*...*/]

function build(){
    var subtasks = scriptBundles.map(function(bundle){
        return gulp.src(bundle.src).pipe(/* concat to bundle.target */)
    })
    return all(subtasks)
}

3
我已经编辑了你的回答,引用了你从软件包文档中复制的内容。你一定也应该在回答中添加一个警告(就像软件包本身所做的那样),它只能与尚未发布的Gulp 4一起使用。 - Louis

3
我不确定我是否正确理解了问题,但如果是的话,这应该是一个简单的解决方案:

最初的回答

gulp.task('sass', ['bootstrap-sass', 'site-sass']);

2
原来 site() 函数返回了一个错误。为了解决这个问题,我需要确保先运行 bootstrap() 函数,所以最终代码如下:
// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = function() {
    return gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  var site = function() {
    return gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  return bootstrap().on('end', site);
});

2
我非常推荐使用任务依赖来解决这个问题,而不是手动完成并且描述不够详细。这不仅是首选的解决方案,而且本质上与您手动完成的方式基本相同。另外,如果您真的喜欢合并流,可以看一下 "stream-combiner"。这里有一个示例供您参考:https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md#combining-streams-to-handle-errors - mikaelb

1
解决方案:调用函数!!!
return Promise.all([bootstrap(), site()])

请注意括号 bootstrap(), site(),以便它们返回一个 promise :)


1
你尝试使用过merge-stream吗?
merge = require('merge-stream');
// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));

  var site = gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));

  return merge(bootstrap, site);

});

请查看https://blog.mariusschulz.com/2015/05/02/merging-two-gulp-streams以获取更多详细信息。


1
合并和仅使用 [task1, task2] 有什么区别? - Denis535

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