简体   繁体   English

如何使用gulp-tap将文件名传递给Gulp管道中的下一个动作?

[英]How do you pass a filename to the next action in a Gulp pipeline using gulp-tap?

I have a Gulp task which takes an HTML file and inlines styles taken from a CSS file using gulp-inline-css. 我有一个Gulp任务,该任务需要一个HTML文件并使用gulp-inline-css内联来自CSS文件的样式。 The original version of my task used the same CSS file for each HTML file. 我任务的原始版本为每个HTML文件使用相同的CSS文件。 Now I would like to have the task choose a CSS file based on the filename of the HTML file it is processing. 现在,我想让任务根据正在处理的HTML文件的文件名选择一个CSS文件。

I am using gulp-tap to get the filename. 我正在用gulp-tap来获取文件名。 The inliner() function takes the path to the CSS file and runs all the inlining stuff. inliner()函数采用CSS文件的路径并运行所有内联的东西。

The following Gulp task runs inliner() for each of the files, but it seems to be failing to inject the results back into the stream. 以下Gulp任务为每个文件运行inliner(),但似乎无法将结果注入回流中。 I've tried a few different approaches, but I can't seem to get the results of inliner() back into the original stream. 我尝试了几种不同的方法,但似乎无法将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();
}

Am I using gulp-tap incorrectly? 我没有正确使用gulp-tap吗? This seems like a very simple use case. 这似乎是一个非常简单的用例。

gulp-foreach was deprecated for gulp-tap and gulp-flatmap. gulp-foreach已不推荐使用gulp-tap和gulp-flatmap。 gulp-flatmap is what you need here, so exactly the same as the answer by elliotregan but like this: 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'));
}

Thanks Elliot, this helped me too, but I couldn't comment on your post as not enough rep yet! 谢谢Elliot,这对我也有帮助,但是由于您的代表还不够,所以我无法评论您的帖子!

When I typed the phrase "for each of the files", I remembered there is a gulp-foreach package, and it worked! 当我输入短语“ for the each of files”时,我记得有一个gulp-foreach包,它起作用了! My new code looks like this: 我的新代码如下所示:

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'));
}

If anyone care to share why my original code was not working...why gulp-tap doesn't seem to allow you to inject stuff back into the pipeline, that would be awesome. 如果有人愿意分享为什么我的原始代码不起作用...为什么gulp-tap似乎不允许您将内容注入管道,那真是太棒了。 Otherwise, lesson learned: 否则,经验教训:

User gulp-foreach instead of gulp-tap if you want to get new back into the pipeline. 如果您想重新使用管道,请使用gulp-foreach而不是gulp-tap

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

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