Gulp watch-按顺序执行任务(同步)

17

我有一系列任务需要从观察器中运行,但我无法让它们按顺序触发:

以下是gulp任务和观察器的代码。

gulp.task('app_scss', function(){
    return gulp.src(appScssDir + '/main.scss')
        .pipe(sass({ style: 'compressed' }).on('error', gutil.log))
        .pipe(autoprefix('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
        .pipe(gulp.dest(appBuilderDir));
});

gulp.task('app_vendor_css', function(){
    return gulp.src(appProviderCssDir + '/*.css')
        .pipe(minifyCSS({ keepSpecialComments: 0 }))
        .pipe(concat('app_vendor.css'))
        .pipe(gulp.dest(appBuilderDir));

});

gulp.task('app_build_css', function(){
    return gulp.src(appBuilderDir + '/*.css')
        .pipe(concat('style.css'))
        .pipe(gulp.dest(targetCssDir));
});


gulp.task('watch', function () {
    gulp.watch(appScssDir + '/**/*.scss', ['app_scss', 'app_build_css']);
});

gulp.task('default', ['app_build_clean', 'app_scss', 'app_vendor_css', 'app_build_css', 'watch']);

当我更新一个scss文件时,它应该编译并创建一个单独的css文件。然后构建任务将该文件与供应商文件连接起来。但每次保存文件时,它总是落后一步。请参考这个视频作为例子: http://screencast.com/t/065gfTrY 我已经重命名了任务,在观察回调中改变了顺序等。
我是否犯了一个明显的错误?
4个回答

21

使用GULP 3时,我使用run-sequence包来帮助按顺序运行任务而不是并行运行。例如,这是我如何配置我的watch任务:

var gulp = require('gulp'),
    runSequence = require('run-sequence');

gulp.task('watch', function() {
    gulp.watch('templates/**/*.html', function(){ runSequence('templates', 'bundleJS') });
});
上面的示例展示了一个典型的 `watch` 任务,它将使用要监听的文件钩入 `gulp.watch` 方法,并在检测到更改时运行回调函数。然后,在某个 `watch` 的回调函数中调用 `runSequence` 函数并传入要以同步方式运行的任务列表,与默认的并行运行任务的方式不同。

很好,但更好的是:gulp.watch('templates/**/*.html', () => runSequence('templates', 'bundleJS')) - dimpiax
1
在这个例子中不需要使用gulp-watch。var watch从未被使用过。gulp.watch可以在var gulp上使用。gulp-watch类似于gulp.watch,但比gulp.watch拥有更多的优势。 - Joe Hawkins
这个插件是一个临时修复。作者在文档中指定了这一点。在gulp 4中,任务将按顺序执行,如gulp.watch([bases.assets + paths.sass], ['sass','styles'])所指定的那样。sass任务将首先被执行,然后是styles任务。 - Cengkuru Michael
@CengkuruMichael - 是的,这已经是众所周知的事情了。这个“临时”的修复方法已经成为标准... Gulp 4似乎永远不会发布,因为他们的Twitter页面上没有任何更新,Github上的分支也没有任何进展。 - vsync

20

除非您声明依赖项(或使流管道相互连接),否则Gulp会将所有任务“同时”启动。

例如,如果您想让任务app_build_css等待任务app_scssapp_vendor_css完成,请声明这些依赖关系。

gulp.task('app_scss', function(){
    return gulp.src(appScssDir + '/main.scss')
        .pipe(sass({ style: 'compressed' }).on('error', gutil.log))
        .pipe(autoprefix('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
        .pipe(gulp.dest(appBuilderDir));
});

gulp.task('app_vendor_css', function(){
    return gulp.src(appProviderCssDir + '/*.css')
        .pipe(minifyCSS({ keepSpecialComments: 0 }))
        .pipe(concat('app_vendor.css'))
        .pipe(gulp.dest(appBuilderDir));

});

gulp.task('app_build_css', ['app_scss', 'app_vendor_css'], function(){
    return gulp.src(appBuilderDir + '/*.css')
        .pipe(concat('style.css'))
        .pipe(gulp.dest(targetCssDir));
});


gulp.task('watch', function () {
    gulp.watch(appScssDir + '/**/*.scss', ['app_build_css']);
});

gulp.task('default', ['app_build_clean', 'app_build_css', 'watch']);

查看Gulp.task()文档


太好了。那个问题让我抓狂了。谢谢。 - Lee
是的,我也是,直到我阅读了文档。使用回调函数和承诺(promises)也非常有趣,因为你可以创建更复杂的场景,如果你的项目构建需要它们。 - AntouanK
简单高效,也适用于例如两个任务都在默认任务中的情况,无需进一步调整。如果您的场景不太复杂,我更喜欢这个答案。 - benzkji

3

Gulp v4

自2017年底发布以来,Gulp v4已经出现了将近一年的时间。它提供了一些很好的方法来使用他们的库bach来排序任务。

https://github.com/gulpjs/bach

注意:我建议您升级到Gulp v4,因为v3存在一些安全漏洞[我不确定是否已被修补]。

快速示例

Gulp v4引入了gulp.seriesgulp.parallel,这使您可以创建任务并选择按顺序、并行或混合运行的任务,如下所示。

说明:这将在并行中运行scssjs任务,一旦完成后,它将在系列中运行watch任务。

const defaultTasks = gulp.series(
  gulp.parallel(scss, js),
  watch
);
defaultTasks.description = 'Builds scss, and js, then watches them for changes and rebuilds upon change.';

module.exports = {
  default: defaultTasks,
  scss,
  js
}

扩展示例

这是一个简化版的gulp文件示例。

const gulpScss = require('gulp-sass');
const gulpBabel = require('gulp-babel');

const paths = {
  scss: [
    'public/stylesheets/*.scss'
  ],
  js: [
    'public/js/*.js'
  ]
};

const scss = () => {
  return gulp.src(paths.scss)
    .pipe(gulpScss)
    .pipe(gulp.dest('dist'));
}
scss.description = 'Transpiles scss files to css.';

const js = () => {
  return gulp.src(paths.js)
    .pipe(gulpBabel({
      presets: ['@babel/env']
    }))
    .pipe(gulp.dest('dist'));
}
js.description = 'Transpiles JS with babel';

const watch = () => {
  gulp.watch(paths.scss, scss);
  gulp.watch(paths.js, js);
}
watch.description = 'Watches for changes to files and runs their associated builds.';

const defaultTasks = gulp.series(
  gulp.parallel(scss, js),
  watch
);
defaultTasks.description = 'Builds scss, and js, then watches them for changes and rebuilds upon change.';

module.exports = {
  default: defaultTasks,
  scss,
  js
}


0
我发现使用以下语法定义“系列”任务非常有用:

gulp.task('jsLib', gulp.series(
    function copiaLibJs () {
        return gulp
            .src(paths.lib.files)
            .pipe(rename(function(path) {
                path.dirname = path.dirname.replace(/\/dist/, '').replace(/\\dist/, '');
            }))
            .pipe(gulp.dest(paths.lib.dest));
    },
    function fontAwesomeCss(){
        return gulp.src('node_modules/font-awesome/css/**').pipe(gulp.dest(paths.css.dest));
    },
    function fontAwesomeFonts(){
        return gulp.src('node_modules/font-awesome/fonts/**').pipe(gulp.dest(paths.font.dest));
    }

));

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