【问题标题】:How do I pass gulp frontmatters output to another plugin in Gulp?如何将 gulp frontmatters 输出传递给 Gulp 中的另一个插件?
【发布时间】:2014-05-20 15:04:23
【问题描述】:

我想将 gulp frontmatters 输出传递给我在 Gulp(gulp 模板)中使用的另一个函数。我认为我的语法是正确的,但一定是做错了什么,因为它不起作用。

我使用的 gulp 插件是:Gulp frontmatterGulp template。我正在尝试将一个名为page 的对象从frontmatter() 传递给template(),如下所示:

.pipe(frontMatter({
  property: 'page' // the name of the property added to the file object
}))
.pipe(template(page)) // passing the page object to the template plugin here

这行不通。我做错了什么?


供参考:这是我的 gulpfile.js 中的完整代码

// Gulp modules
var gulp        = require( 'gulp' );
var markdown    = require( 'gulp-markdown' );
var frontMatter = require( 'gulp-front-matter' );
var template    = require( 'gulp-template' );

gulp.task('default', function () {
  return gulp.src( ['./**/*.{md,markdown}'] )
    .pipe(frontMatter({
      property: 'page' // property added to file object
    }))
    .pipe(template(page))
    .pipe(markdown())
    .pipe(gulp.dest(grOutput));
});

这是我正在使用的模板(test/test.md):

---
name: MyName
---
Text
<%= page.name %>
Text

这是我收到的错误消息:

[gulp] Using gulpfile D:\Dropbox\Github\graphene\gulpfile.js
[gulp] Starting 'default'...
[gulp] 'default' errored after 7.49 ms page is not defined

D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\event-stream\node_modules\map-stream\index.js:103
        throw err
              ^
expected '<document start>', but found <block mapping end>
  in "undefined", line 12, column 1
    at ParserError.YAMLError (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\errors.js:72:46)
    at ParserError.MarkedYAMLError (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\errors.js:88:45)
    at new ParserError (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\parser.js:17:48)
    at Constructor.Parser.Parser.parse_document_start (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\parser.js:158:17)
    at Constructor.Parser.Parser.check_event (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\parser.js:63:48)
    at Constructor.Composer.Composer.get_single_node (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\composer.js:55:17)
    at Constructor.BaseConstructor.BaseConstructor.get_single_data (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\constructor.js:78:19)
    at load (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\node_modules\yaml-js\lib\yaml.js:113:19)
    at parse (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\index.js:26:27)
    at extractor (D:\Dropbox\Github\graphene\node_modules\gulp-front-matter\node_modules\front-matter\index.js:19:34)

【问题讨论】:

    标签: javascript node.js gulp lodash


    【解决方案1】:

    你从未定义过page.. 所以你得到:

    [gulp] 'default' 在 7.49 毫秒页面未定义后出错

    gulp-front-matter 插件将前面的内容添加到文件对象的属性中,gulp 通过pipe 方法传递。所以你需要使用另一个可以使用该属性的插件,如果你想对前端做一些事情。否则,只需将 remove: true 选项添加到前面的选项哈希中。

    从那里您应该可以只调用template()(没有选项),我不确定,但也许可以从您的模板访问page 属性。..

    编辑

    当 gulp 发送它时,grunt-template 插件不会从包含我们数据的文件对象中获取任何数据。我的解决方案是直接使用 lodash 模板,并通过这种方式传递块和前端数据。

    var gulp = require('gulp');
    var markdown = require('gulp-markdown');
    var frontMatter = require('gulp-front-matter');
    var through = require('through2');
    var template = require('lodash').template;
    
    gulp.task('default', function () {
      return gulp.src('./template.md')
        .pipe(frontMatter({ // optional configuration
          property: 'page'
        }))
        .pipe(through.obj(function (file, enc, callback) {
          if (file.isBuffer()) {
            file.contents = new Buffer(template(file.contents, file.page));
          }
    
          this.push(file);
          return callback();
        }))
        .pipe(markdown())
        .pipe(gulp.dest('dist'));
    });
    

    【讨论】:

    • 但我不是告诉frontMatter 用.pipe(frontMatter({property:"page"})) 定义page 对象吗?另外,我相信remove:true 标志只是告诉frontmatter 从vinyl 文件中删除yaml frontmatter 标头(默认值已经是true)。所以恐怕我不太明白你的答案。你的解决方案是什么?
    • 您介意详细说明您的答案吗?我已经创建了一个赏金,所以如果你想要的话,我可以给你。
    • @Sam frontMatter 插件所做的是在 gulp 传递给它的数据上创建一个“页面”变量。但是您在当前范围内使用了一个未声明的变量,它不是文件数据。
    • 在这里查看变量基础知识:developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
    • 感谢您的回复!我已经尝试过您的解决方法,但它仍然返回 ReferenceError: page is not defined..
    【解决方案2】:

    看起来 gulp-template 设置为侦听名为“file.data”的文件对象的属性。在这种情况下,使用 gulp-data 插件https://www.npmjs.org/package/gulp-data 很容易实现。 README 中有一个关于如何传递 frontmatter 的示例。

    【讨论】:

      【解决方案3】:

      不幸的是,这个问题的所有答案都对我有用。我使用gulp-vartree 取得了相当大的进展,它可以将属性存储在变量中,这正是我想要做的。

      但最后,我遇到了新问题,所以我最终切换到 grunt stencil,因为它完全符合我的要求,没有任何麻烦。

      【讨论】:

      • 似乎很遗憾它不是 gulp 的选项,不是吗?
      • 查看我上面关于使用 gulp-data 的回答
      【解决方案4】:

      在寻找这个问题的解决方案但一无所获后,我自己构建了一个(新的 gulp 用户,所以如果这是一个糟糕的解决方案,我深表歉意,但至少它是一些东西):

      var fs     = require('fs');
      var gulp   = require('gulp');
      var gutil  = require('gulp-util');
      var tap    = require('gulp-tap');
      var header = require('gulp-header');
      var footer = require('gulp-footer');
      var concat = require('gulp-concat');
      var fm     = require('gulp-front-matter');
      var marked = require('gulp-markdown');
      
      // Build a single index.html from a glob of markdown files, specifically for use with impressjs.
      gulp.task('build:index', function (callback) {
      
        // Parse a glob of markdown files.
        gulp.src(src + '/markup/**/*.md')
      
          // Strip the frontmatter - it gets shoved into file.fm['...']
          .pipe(fm ({property: 'fm', remove: true}))
      
          // Expose file.fm['..'] variables generated by gulp-front-matter using gulp-tap.
          // Because we don't want to write empty tags if the values aren't defined, we
          // set default variables that initialize the entire tag attribute.
          .pipe(tap(function(file, t) {
            slide_id = file.fm['id']==undefined ? '' : 'id="' + file.fm['id'] + '"'
            slide_class = file.fm['class']==undefined ? '' : 'class="' + file.fm['class'] + '"'
            slide_properties  = file.fm['properties']
          }))
      
          // Generate html from the remaining markdown.
          .pipe(marked())
      
          // Wrap the markup in div tags, generated from the frontmatter.
          // If the variables are not defined, an error is not generated, they simply are not
          // written. Perfect behavior for my use case, but probably should be more explicit.
          .pipe(header('<div <%= slide_id %> <%= slide_class %> <%= slide_properties %>>\n'))
          .pipe(footer('</div>\n'))
      
          // Concatenate all the html into a single file.
          .pipe(concat('index.html'))
      
          // Wrap the generating html in our impressjs header and footer.
          .pipe(header(fs.readFileSync('src/templates/impress-header.tpl', 'utf8')))
          .pipe(footer(fs.readFileSync('src/templates/impress-footer.tpl', 'utf8')))
      
          // Write the index file.
          .pipe(gulp.dest(dist))
      
          // Fill up our logs.
          gutil.log('Recompiled index.html')
      });
      

      【讨论】:

        【解决方案5】:

        对我来说,解决方案是使用 gulp-data 并稍作改动(插件 README 中描述的方法不起作用):

        ...
        .pipe(frontMatter())
        .pipe(data(function(file) {
            return file.frontMatter;
        }))
        .pipe(template())
        ...
        

        或使用咖啡脚本:

        ...
        .pipe frontMatter()
        .pipe data (file) ->
            file.frontMatter
        .pipe template()
        ...
        

        【讨论】:

          【解决方案6】:

          看起来不错 如果您使用

          显示错误怎么办

          error_reporting(E_ALL);

          或类似的?

          【讨论】:

          猜你喜欢
          • 2015-06-29
          • 2017-11-14
          • 1970-01-01
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-16
          相关资源
          最近更新 更多