如何在进行更改之前解析整个gulp流?

时间:2016-09-29 05:08:47

标签: gulp node-streams

我正在尝试使用Gulp制作静态网站。我遇到了一个有趣的问题,即翻译我在之前版本中编写的概念以及如何使用Gulp实现它。

如果我有动态包含其他文件的文件,那么其中一个概念。

---
title: Table of Contents
include:
  key: book
  value: book-1
---

Introduction.

然后,其他文件包含该密钥。

---
title: Chapter 1
book: book-1
---
It was a dark and stormy night...

......和:

---
title: Chapter 2
book: book-1
---

期望的最终结果是:

---
title: Table of Contents
include:
  key: book
  value: book-1
  files:
    - path: chapters/chapter-01.markdown
      title: Chapter 1
      book: book-1
    - path: chapters/chapter-02.markdown
      title: Chapter 2
      book: book-1
---

基本上,扫描文件并将data元素作为序列插入到包含的页面中。我不知道提前包含的所有类别或标签(我将30-40个Git存储库合并在一起),所以我不想为每个类别创建一个任务。

我希望的是:

return gulp.src("src/**/*.markdown")
  .pipe(magicHappens())
  .pipe(gulp.dest("build"));

问题似乎是流如何工作。我无法将两个方法链接在一起,因为每个文件都从一个管道传递到下一个管道。要插入include.files元素,我必须解析所有输入文件(它们甚至不在子目录中)以确定在我完成之前包含哪些文件。

似乎我必须“拆分流”,解析第一个获取数据,将第二个链接到第一个结束,然后使用第二个将结果传递出方法。我只是不完全确定如何做到这一点,并希望得到一些指示或建议。我的google-fu并没有提出好的建议,甚至没有提到我重组的提示。谢谢。

1 个答案:

答案 0 :(得分:0)

经过大量的摸索,我想出了这个:

var through = require('through2');
var pumpify = require("pumpify");

module.exports = function(params)
{
    // Set up the scanner as an inner pipe that goes through the files and
    // loads the metadata into memory.
    var scanPipe = through.obj(
        function(file, encoding, callback)
        {
            console.log("SCAN: ", file.path);
            return callback(null, file);
        });

    // We have a second pipe that does the actual manipulation to the files
    // before emitting.
    var updatePipe = through.obj(
        {
            // We need a highWaterMark larger than the total files being processed
            // to ensure everything is read into memory first before writing it out.
            // There is no way to disable the buffer entirely, so we just give it
            // the highest integer value.
            highWaterMark: 2147483647
        },
        function(file, encoding, callback)
        {
            console.log("UPDATE: ", file.path);
            return callback(null, file);
        });

    // We have to cork() updatePipe. What this does is prevent updatePipe
    // from getting any data until it is uncork()ed, which we won't do, or
    // the scanPipe gets to the end.
    updatePipe.cork();

    // We have to combine all of these pipes into a single one because
    // gulp needs a single pipe  but we have to treat these all as a unit.
    return pumpify.obj(scanPipe, updatePipe);
}

我认为评论非常清楚,但我必须将两个管道合并为一个(使用pumpify),然后使用cork停止处理第二个流,直到第一个流为完成(自动uncork d第二个流)。由于我有大量的文件,我不得不使用更高的水印来避免第一个文件挨饿。