Как проанализировать весь поток gulp перед внесением изменений?

Я пытаюсь сделать статический сайт с помощью Gulp. Я столкнулся с интересной проблемой перевода концепции, которую я написал в предыдущей версии, и как реализовать ее с помощью Gulp.

Одно из понятий, Если у меня есть файлы, которые динамически включают другие файлы.

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

Introduction.

Затем другие файлы включают have that key.

---
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 ответ

  1. После многих возиться, я придумал это:

    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, чтобы остановить второй поток от обработки, пока не будет сделан первый (который автоматически uncorkd второй поток). Так как у меня было большое количество файлов, я должен был использовать гораздо более высокий водяной знак, чтобы не голодать первый.