【问题标题】:Gulp: how to pass parameters from watch to tasksGulp:如何将参数从手表传递到任务
【发布时间】:2015-09-19 15:54:12
【问题描述】:

使用 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'ed 任务?

【问题讨论】:

    标签: gulp gulp-watch


    【解决方案1】:

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

    gulp.watch 是一个 eventEmitter,它发出一个 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' }
    

    此信息可能会通过其任务函数或gulp.src 的行为传递给template 任务。

    任务函数本身只能接收回调(https://github.com/gulpjs/gulp/blob/master/docs/API.md#fn),无法接收 gulp 使用的黑胶文件(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/'))
    }
    

    【讨论】:

      【解决方案2】:

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

      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 文件的目录,我将在其中使用 cmets。我在看着他们。当文件被修改时,监视处理被触发,然后我只需要处理被修改的文件。为了删除 cmets,我使用了 json-comment-strip 插件。另外,我需要做更多的治疗。删除多个连续的换行符。 无论如何,首先我需要将路径传递给我们可以从事件参数中恢复的文件我通过全局变量将其传递给任务,仅此而已。允许传递数据。

      注意:尽管这与问题无关,但在我的示例中,我需要处理从插件处理中流出的流。我使用了on("data" 事件。它是异步的。所以任务将在工作完全结束之前标记结束(任务到达结束,但启动的异步函数将继续处理一点)。所以你在任务结束时进入控制台的时间,不是整个处理的时间,而是任务块结束的时间。只是你知道的。对我来说没关系。

      【讨论】:

        猜你喜欢
        • 2015-04-16
        • 2019-03-10
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多