Gulp: 如何从 watch 传递参数到 tasks

5

在使用Gulp时,你经常会看到这样的模式:

gulp.watch('src/*.jade',['templates']);

gulp.task('templates', function() {
  return gulp.src('src/*.jade')
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('dist/'))
    .pipe( livereload( server ));
});

这实际上是否将被监视的文件传递到模板任务中?这些文件如何覆盖/扩展/过滤src任务?
2个回答

8

我之前也有同样的问题,经过一番挖掘后得出了以下结论。

gulp.watch是一个事件发射器,会发出change事件,因此您可以这样做:

var watcher = gulp.watch('src/*.jade',['templates']);

watcher.on('change', function(f) {
  console.log('Change Event:', f);
});

你会看到这个:

Change Event: { type: 'changed',
  path: '/Users/developer/Sites/stackoverflow/src/touch.jade' }

这些信息可以通过template任务函数或gulp.src的行为传递给它。

任务函数本身只能接收回调(https://github.com/gulpjs/gulp/blob/master/docs/API.md#fn),无法接收有关gulp使用的vinyl文件(https://github.com/wearefractal/vinyl-fs)的任何信息。

启动任务的源(在此情况下为.watch或gulp命令行)不会影响gulp.src('src-glob',[options])的行为。 'src-glob'是一个字符串(或字符串数组),而optionshttps://github.com/isaacs/node-glob#options)与任何文件更改无关。

因此,我没有看到.watch直接影响触发任务的行为的任何方法。

如果您想仅处理更改过的文件,可以使用gulp-changedhttps://www.npmjs.com/package/gulp-changed)来配合gulp.watch使用,或者您也可以使用gulp-watch。此外,您还可以这样做:
var gulp = require('gulp');
var jade = require('gulp-jade');
var livereload = require('gulp-livereload');

gulp.watch('src/*.jade', function(event){
  template(event.path);
});

gulp.task('templates', function() {
  template('src/*.jade');
});

function template(files) {
  return gulp.src(files)
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('dist/'))
}

1

将参数或数据从观察者传递到任务的一种可能的方式是通过使用全局变量,或者在两个块作用域中都存在的变量。以下是一个示例:

gulp.task('watch', function () {
        //....
        //json comments 
        watch('./app/tempGulp/json/**/*.json', function (evt) {
             jsonCommentWatchEvt = evt; // we set the global variable first
             gulp.start('jsonComment'); // then we start the task
        })
})

//global variable
var jsonCommentWatchEvt = null

//json comments task

gulp.task('jsonComment', function () {
    jsonComment_Task(jsonCommentWatchEvt)
})

以下是执行任务的函数,如果有兴趣可以了解一下,但我并不需要将工作放在另一个函数中,我可以直接在任务中实现它。至于文件,您有全局变量,这里是jsonCommentWatchEvt。但是,如果您不像我这样使用函数,则一个好的做法是将全局变量的值分配给一个本地变量,您将使用该变量。并且您需要在任务的所有顶部条目中执行此操作,以避免使用全局变量本身,并避免它被当前运行任务的另一个监视处理触发更改的问题。

function jsonComment_Task(evt) {
    console.log('handling : ' + evt.path);
    gulp.src(evt.path, {
        base: './app/tempGulp/json/'
    }).
    pipe(stripJsonComments({whitespace: false})).on('error', console.log).
    on('data', function (file) { // here we want to manipulate the resulting stream

        var str = file.contents.toString()

        var stream = source(path.basename(file.path))
        stream.end(str.replace(/\n\s*\n/g, '\n\n'))
        stream.
        pipe(gulp.dest('./app/json/')).on('error', console.log)
    })
}

我有一个不同json文件的目录,其中我将在它们上使用注释。我正在监视它们。当文件被修改时,观察处理被触发,然后我只需要处理被修改的文件。为了删除注释,我使用了json-comment-strip插件。此外,我还需要进行更多的处理,以删除多个连续的换行符。无论如何,首先我需要将文件路径传递给可以从事件参数中恢复的文件我通过全局变量将其传递给任务,该变量仅执行此操作。允许传递数据。 注意:尽管这与问题没有关系,在我的示例中,我需要处理从插件处理中获取的流。我使用了on("data"事件。它是异步的。因此,在工作完全结束之前,任务将标记结束(任务到达结束,但启动的异步函数将继续处理一段时间)。因此,您在控制台上获得的时间是任务块结束的时间,而不是整个处理的时间。你知道就好了。对我来说没关系。

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