Возврат результата отложенной функции в следующую трубу Gulp с помощью gulp-tap - PullRequest
0 голосов
/ 12 апреля 2019

Я создаю простой статический сайт, на котором в процессе разработки я использую Handlebars.js и выполняю некоторые вызовы API для заполнения шаблонов Handlebars.Но для производства я хочу предварительно скомпилировать все шаблоны в статический HTML.

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

gulp.task('compileHtml', () => {
  return gulp
    .src('index.html')
    .pipe(someThing())
    .pipe(anotherThing())
    .pipe(compileTemplates())
    .pipe(someOtherThing())
    .pipe(gulp.dest('build'));
});

В моей функции compileTemplates я использую gulp-tap и jsdom , чтобы в основном запустить файл с соответствующими сценариями для выполнения вызовов API и заполнения шаблонов Handlebars., затем удалите эти сценарии и отправьте обратно скомпилированный HTML-код в следующий канал.Но у меня возникают проблемы с отложением отправки нового DOM до тех пор, пока у jsdom не будет достаточно времени для запуска всех сценариев.

Вот что у меня есть:

const compileTemplates = file => {
  return tap(file => {
    const dom = new JSDOM(file.contents,
      {
        runScripts: 'dangerously',
        resources: 'usable',
        beforeParse(window) {
          window.fetch = require('node-fetch');
        },
      },
    );
    const document = dom.window.document;
    const script = document.querySelector('script[src$="handlebars.min.js"]');

    // dom.serialize() still contains my uncompiled templates at this point
    setTimeout(() => {
      script.remove();
      file.contents = Buffer.from(dom.serialize()); // this is what I want to return from this function
    }, 2500);
  });
};

Я знаюМне, вероятно, нужно использовать обещание, чтобы отправить обратно file.contents, когда оно будет готово, но я не очень хорош в обещаниях или в Gulp.

Я пытался вернуть обещание, которое разрешается в течение тайм-аута, но яв итоге получим TypeError: dest.on is not a function, потому что следующий канал в конечном итоге ожидает file, а не обещание.

Как я могу рефакторинг либо отложить отправку моих манипулированных file на следующий канал, либо отослать обратнообещание из этой функции, а затем разрешить это обещание для нового file в моем compileHtml задании?

Я использую Gulp 4.

1 Ответ

0 голосов
/ 19 апреля 2019

После консультации Используя setTimeout в цепочке обещаний , я выяснил, как разрешить обещание после истечения времени ожидания.

const compileTemplates = file => {
  return tap(file => {
    const dom = new JSDOM(file.contents,
      {
        runScripts: 'dangerously',
        resources: 'usable',
        beforeParse(window) {
          window.fetch = require('node-fetch');
        },
      },
    );
    const document = dom.window.document;
    const script = document.querySelector('script[src$="handlebars.min.js"]');

    new Promise(resolve => {
      setTimeout(resolve, 2500);
    }).then(() => {
      script.remove();
      file.contents = Buffer.from(dom.serialize());
    });
  });
};

Однако это не полностью решило мою проблему, потому что яМне нужно было дождаться разрешения этого обещания, прежде чем отправлять новый file на следующий канал в моей задаче gulp, но я не смог найти хорошую документацию по обратным вызовам в gulp-tap.

Так что я закончилвместо этого используйте через2 .

const compileHtml = file => {
  return through2.obj(function(file, encoding, callback) {
    const dom = new JSDOM(file.contents,
      {
        runScripts: 'dangerously',
        resources: 'usable',
        beforeParse(window) {
          window.fetch = require('node-fetch');
        },
      },
    );
    const document = dom.window.document;
    const script = document.querySelector('script[src$="handlebars.min.js"]');

    new Promise(resolve => {
      setTimeout(resolve, 2500);
    }).then(() => {
      script.remove();
      file.contents = Buffer.from(dom.serialize());
      this.push(file);
      callback();
    });
  });
}

Если кто-то знает, как будет выглядеть эта функция, используя gulp-tap, не стесняйтесь написать ответ!

...