简体   繁体   English

在Node.js / Gulp中重用流管道/子管道

[英]reusing stream pipeline/sub-pipeline in Node.js/Gulp

starting out with streams/gulp/vinyl and trying to clean up/DRY my gulpfile using stream-combiner2 . 从stream / gulp / vinyl开始,并尝试使用stream-combiner2清理/干燥我的gulpfile。 so far it is working well except now i need to run a sub-pipeline inside another pipeline (simplified psuedocode-ish): 到目前为止,它运行良好,只是现在我需要在另一个管道(简化的psuedocode-ish)中运行一个子管道:

var logger = require("gulp-logger"),
HTMLPrettify = require("gulp-html-prettify"),
combiner = require("stream-combiner2"),
through = require("through2"),
tap = require("gulp-tap"),
_ = require("lodash");


preprocessPipeline = function() {
  return combiner.obj(getFrontMatter(), processTemplates());
};


gulp.task("build", ["clean"], function() {
    return gulp.src("in/**/*.html")
        .pipe(preprocessPipeline())
        .pipe(tap(function(file) {
            var data, dataSources;
            dataSources = getDataSources(file);
            data = {};

            /* PAUSE MAIN PIPELINE HERE */
            /* RUN THIS SUB PIPELINE BELOW */
            gulp.src(dataSources)
                .pipe(preprocessPipeline())
                .pipe(tap(function(file) {
                    _.merge(data, file.data);
                }));

            file.data = data;
            /* RESUME MAIN PIPELINE */
        }))
        .pipe(HTMLPrettify())
        .pipe(gulp.dest("out"));
});

as you can see, inside the main "build" pipeline i am trying to do the following for each vinyl file object that comes down the main pipeline: 如您所见,在主“构建”管道中,我试图对来自主管道的每个乙烯基文件对象执行以下操作:

  • pause execution of main "build" pipeline 暂停执行主要的“构建”管道
  • get the data source paths for the current vinyl file via the synchronous getDataSources() function 通过同步getDataSources()函数获取当前乙烯基文件的数据源路径
  • use another sub pipeline to process those data source paths, reusing the preProccessPipeline and eventually merging their data 使用另一个子管道来处理这些数据源路径,重用preProccessPipeline并最终合并其数据
  • finally the merged data from the data sources is added the the vinyl file in the main pipeline and execution continues in the main pipeline 最后,来自数据源的合并数据在主管道中添加乙烯基文件,并在主管道中继续执行

gulp.src() looks like the perfect way to load these data source files into the sub-pipeline but the main pipeline seems to be completing before the sub-pipeline starts. gulp.src()看起来是将这些数据源文件加载到子管道中的理想方法, gulp.src()道似乎在子管道开始之前gulp.src()完成。

also, i am starting to realize that perhaps my pipelines are looking like synchronous function flow and most likely i am missing a key piece of the stream/node.js puzzle. 另外,我开始意识到也许我的管道看起来像同步函数流,并且很可能我错过了stream / node.js难题的关键部分。

related docs that have helped me reuse pipelines but not with sub-pipelines: 帮助我重用管道但不使用子管道的相关文档:

related issues: 相关问题:

thanks. 谢谢。

Seems like you're using gulp as a templating engine of sorts—totally doable. 似乎您正在使用gulp作为各种模板引擎—完全可行。

Gulp lets you specify which tasks are dependent on others, so you could break out that sub-pipeline into a new task, say "buildDataFiles" , then have your build task depend on that one ie Gulp允许您指定哪些任务依赖于其他任务,因此您可以将该子管道分解为一个新任务,例如"buildDataFiles" ,然后使构建任务依赖于该任务,即

gulp.task("build", ["buildDataFiles", "clean"], function(){

But the problem with this approach is, as you said, "it is not possible to know the data file(s) associated with a template file until the template is processed." 但是,正如您所说,这种方法的问题是“在处理模板之前,不可能知道与模板文件关联的数据文件”。 If you're sure there's no way around that, it gets trickier. 如果您确定无法解决此问题,它将变得更加棘手。 What if instead you broke out the main pipe into a "processTemplate" task, the "build" task then only handles the sub-pipeline but depends on "processTemplate" ? 相反,如果您将"processTemplate"分解为"processTemplate"任务,那么"build"任务仅处理子管道,但取决于"processTemplate"怎么办? It could look something like this: 它可能看起来像这样:

gulp.task("processTemplate", ["clean"], function() {
  gulp.src("in/**/*.html")
    .pipe(preprocessPipeline())
    .pipe(gulp.dest("build/temp"));
}

gulp.task("build", ["processTemplate"], function() {
  gulp.src("build/temp/*.html")
    .pipe(tap(function(file) {
      var data, dataSources;
      dataSources = getDataSources(file);
      data = {};

      gulp.src(dataSources)
        .pipe(preprocessPipeline())
        .pipe(tap(function(file) {
          _.merge(data, file.data);
        }));

      file.data = data;

    }))
  .pipe(HTMLPrettify())
  .pipe(gulp.dest("out"));
}

It looks really similar, but the problem your running into requires that the templates be processed first, then the data files. 看起来确实很相似,但是遇到的问题是首先要处理模板,然后再处理数据文件。 I would try checking out gulp-consolidate , it may help you out. 我会尝试检查gulp-consolidate ,它可能会对您有所帮助。

I find stream-combiner much more straight to the point 我发现流合并器更直接

function coffeePipe() {
  return Combine(
    coffeescript(),
    coffeelint.reporter('fail')
  )
}
//usage:
gulp.src().pipe(coffeePipe());

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

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