简体   繁体   English

Gulp:我该如何处理从未完成的任务?

[英]Gulp: how do I pipe through a task that never finishes?

I'm trying to write a gulp plugin for watchify that allows me to pipe files into it. 我正在尝试编写一个适用于watchify插件,允许我将文件通过管道插入其中。 The problem is that my task never actually "finishes", as it sits there and monitors a bunch of files and re-builds as necessary. 问题在于我的任务从未真正“完成”,因为它坐在那里并监视一堆文件并根据需要重新构建。

So how do I send code "through" this plugins? 那么,如何通过此插件“发送”代码?

Right now, my task calling the plugin is simplified to: 现在,我调用插件的任务简化为:

gulp.src( '/path/to/js/*.js' )
    .pipe( watchifyPlugin() )
    .pipe( cfg.gulp.dest( '/path/to/build' ) )

My watchifyPlugin is: 我的watchifyPlugin是:

module.exports = function( opts ){
    return through.obj( function( file, enc, cb ){
        // watchify file
        self.push( data ); // whenever any .js files are updated

        // never call cb()
    }
}

Now this works fine for the first .js file that my glob finds. 现在,这对于我的glob找到的第一个.js文件可以正常工作。 Any other files never actually get to my plugin, however, and I'm assuming it's because I never call cb() . 但是,实际上没有任何其他文件到达我的插件,因为我从未调用cb()

So how do I do this? 那么我该怎么做呢? Is there a way to keep writing to the stream without calling cb() , which closes it, yet still allow the previous pipes to continue? 有没有一种方法可以继续写入流而无需调用cb()来关闭流,但仍允许先前的管道继续运行?

in other words: 换一种说法:

  • index.js index.js
    • watchify()
    • pipes to dest() just fine, even when I call self.push() again and again 即使我一次又一次地调用self.push() ,也可以将管道传递给dest()很好
    • cb() never called cb()从未调用
  • index2.js index2.js
    • watchify() never called until cb() called for index.js , but this "closes" the index.js pipe watchify()直到cb()调用index.js时才调用,但这会“关闭” index.js管道

You are using through in a wrong way, you must call the callback when you are done with the file ('data' event). 您使用的方式有误,在处理完文件后必须调用回调(“数据”事件)。 However it is not cb() that closes the stream, it is emitting the end even that does this. 但是,不是cb()关闭该流,即使这样做,它也会发出end

You can delay the end event and keep calling this.push to send out new files. 您可以延迟结束事件并继续调用this.push发送新文件。

Something like 就像是

var Through = require('through2').obj;
var my_plugin = function() {

  var last_file = null; // as an example, last emitted file

  function handle_data = function(file, enc, done) { 
    this.push(file); // emit the file
    this.push(file); // just for kicks, emit it again
    last_file = file;
    done(); // done handling *this* file
  }

  function handle_end = function(done) {
     if(last_file) this.push(last_file); // emit the last file again
     done(); // handled the 'end' event
  }

  return Through(handle_data, handle_end);
}

This would emit each file twice before processing the next file, then when it's done with all files (the end event is received) it emits the last file one more time and then emits the end event. 这将在处理下一个文件之前发射每个文件两次,然后在处理完所有文件(接收到end事件)后,它将再次发射最后一个文件,然后发射end事件。

But why are you not using gulp.watch and just run the task again when something has changed? 但是,为什么不使用gulp.watch并仅在发生更改后再次运行任务? or even use the gulp-watch plugin which emits files when they changed? 甚至使用gulp-watch插件,当它们更改时会发出文件?

This is a very bad idea. 这是一个非常糟糕的主意。 Not everything in gulp needs to be a plugin, and in particular, browerify and watchify plugins are consistently banned. 并非gulp中的所有内容都需要使用插件,尤其是一贯禁止使用browerify和watchify插件。 (See https://github.com/gulpjs/plugins/blob/master/src/blackList.json .) If you want to run watchify, just use watchify directly. (请参阅https://github.com/gulpjs/plugins/blob/master/src/blackList.json 。)如果要运行watchify,只需直接使用watchify。 From https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md : https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md

var gulp = require('gulp');
var source = require('vinyl-source-stream');
var watchify = require('watchify');

gulp.task('watch', function() {
  var bundler = watchify('./src/index.js');

  // Optionally, you can apply transforms
  // and other configuration options on the
  // bundler just as you would with browserify
  bundler.transform('brfs');

  bundler.on('update', rebundle);

  function rebundle () {
    return bundler.bundle()
      .pipe(source('bundle.js'))
      .pipe(gulp.dest('./dist'))
  }

  return rebundle();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM