Gulp: 如何将参数从手表传递给任务

Gulp: how to pass parameters from watch to tasks

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

这是否真的将监视的文件传递到模板任务中?这些 overwrite/extend/filter src 的任务是如何完成的?

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

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

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/Whosebug/src/touch.jade' }

此信息大概可以通过其任务功能或 gulp.src 的行为传递给 template 任务。

任务函数本身只能接收由 gulp 使用的回调 (https://github.com/gulpjs/gulp/blob/master/docs/API.md#fn) and cannot receive any information about vinyl files (https://github.com/wearefractal/vinyl-fs)。

启动任务的源(在本例中为.watch,或gulp 命令行)对gulp.src('src-glob', [options]) 的行为没有影响。 'src-glob' 是一个字符串(或字符串数​​组),options (https://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/'))
}

将观察者的参数或数据传递给任务的一种可能方式。我s 通过使用一个全局变量,或者一个在两个块作用域中的变量。这是一个例子:

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" 事件。它是异步的。所以任务会在工作完全结束之前标记结束(任务到达结束,但启动的异步函数将继续处理一点)。所以你在任务结束时进入控制台的时间不是整个处理的时间,而是任务块结束的时间。只是你知道。对我来说没关系。