Как передать имя файла следующему действию в конвейере Gulp с помощью gulp-tap?

У меня есть задача Gulp, которая берет файл HTML и встроенные стили, взятые из файла CSS, используя gulp-inline-css. Оригинальная версия моей задачи использовала один и тот же файл CSS для каждого файла HTML. Теперь я хотел бы, чтобы задача выбрала файл CSS на основе имени файла HTML, который он обрабатывает.

я использую gulp-tap чтобы получить имя файла. inliner() Функция берет путь к файлу CSS и запускает все встроенные элементы.

Следующая задача Gulp запускает inliner() для каждого из файлов, но, похоже, не удается вставить результаты обратно в поток. Я пробовал несколько разных подходов, но я не могу вернуть результаты inliner() в исходный поток.

gulp.task('inline', inline);

function inline() {
  return gulp.src('dist/**/*.html')
    .pipe(tap( (file, t) => {
      let fileName = path.basename(file.path);
      let cssPath = getStylesheetPathFromHtmlPath(fileName);
      return inliner(cssPath);
    }))
    .pipe(gulp.dest('dist'));
}

function inliner(cssPath) {
  var css = fs.readFileSync(cssPath).toString();
  var mqCss = siphon(css);
  var pipe = lazypipe()
    .pipe(inlineCss, {
      applyStyleTags: false,
      removeStyleTags: true,
      preserveMediaQueries: true,
      removeLinkTags: false
    })
    .pipe(replace, '<!-- <style> -->', `<style>${mqCss}</style>`)
    .pipe(replace, `<link rel="stylesheet" type="text/css" href="css/${getStylesheetNamespace(cssPath)}.css">`, '')
    .pipe($.htmlmin, {
      collapseWhitespace: true,
      minifyCSS: true
    });
  console.log(cssPath)
  return pipe();
}

Я неправильно использую gulp-tap? Это похоже на очень простой вариант использования.

2 ответа

Решение

Когда я набрал фразу "для каждого из файлов", я вспомнил, что есть gulp-foreach пакет, и это сработало! Мой новый код выглядит так:

function inline() {
  return gulp.src('dist/**/*.html')
    .pipe(forEach( (stream, file) => {
      let fileName = path.basename(file.path);
      let cssPath = getStylesheetPathFromHtmlPath(fileName);
      return stream .pipe(inliner(cssPath));
    }))
    .pipe(gulp.dest('dist'));
}

Если кто-то хочет поделиться, почему мой оригинальный код не работает... почему gulp-tap кажется, не позволяет вам вводить вещи обратно в конвейер, это было бы здорово. В противном случае урок усвоен:

пользователь gulp-foreach вместо gulp-tap если вы хотите получить новое обратно в конвейер.

gulp-foreach устарел для gulp-tap и gulp-flatmap. Здесь вам нужно gulp-flatmap, точно такой же, как и ответ от elliotregan, но вот так:

function inline() {
  return gulp.src('dist/**/*.html')
    .pipe(flatmap((stream, file) => {
      let fileName = path.basename(file.path);
      let cssPath = getStylesheetPathFromHtmlPath(fileName);
      return stream 
        .pipe(inliner(cssPath));
    }))
    .pipe(gulp.dest('dist'));
}

Спасибо, Эллиот, это тоже мне помогло, но я не могу прокомментировать ваш пост, так как недостаточно репов!

Другие вопросы по тегам