咕嘟咕嘟插件:拆分乙烯基文件分成多个文件没有正确划分数据

问题描述:

我有一个咕嘟咕嘟插件,stratic-paginate-indexes咕嘟咕嘟插件:拆分乙烯基文件分成多个文件没有正确划分数据

'use strict'; 

var through2 = require('through2'), 
    path = require('path'); 

function makePage(originalFile, page, pageNumber) { 
    var newFile = originalFile.clone(); 
    newFile.data = newFile.data || {}; 
    newFile.data.posts = page; 
    newFile.data.page = pageNumber; 

    if (pageNumber === 1) return newFile; 

    var filePath = path.parse(newFile.path); 
    filePath.dir = path.join(filePath.dir, 'page', pageNumber.toString()); 
    newFile.path = path.format(filePath); 

    return newFile; 
} 

module.exports = function() { 
    return through2.obj(function(file, enc, callback) { 
     var pageNumber = 1, 
      pageFiles = [], 
      page = []; 

     while (file.data.posts > 0) { 
      page = file.data.posts.splice(5); 

      var newFile = makePage(file, page, pageNumber); 
      pageFiles.push(newFile); 

      pageNumber++; 
     } 

     // Per-index page counts 
     pageFiles.forEach(function(file) { 
      file.data.pageCount = pageFiles.length; 
      this.push(file); 
     }, this); 

     callback(); 
    }); 
}; 

这个插件旨在利用在代表博客文章的索引乙烯文件。对于索引file,file.data.posts是一个Vinyl文件数组,表示要包含在呈现的页面上的各个帖子。以下是我正在使用的Gulp任务:

var jade = require('gulp-jade'); 
var rename = require('gulp-rename'); 
var remark = require('gulp-remark'); 
var remarkHtml = require('remark-html'); 
var adjustHeaders = require('remark-rewrite-headers'); 
var parse = require('stratic-parse-header'); 
var dateInPath = require('stratic-date-in-path'); 
var postsToIndex = require('stratic-posts-to-index'); 
var paginateIndexes = require('stratic-paginate-indexes'); 
var addsrc = require('gulp-add-src'); 


gulp.task('post-index', function() { 
    return gulp.src('src/blog/*.md') 
       .pipe(parse()) 
       .pipe(remark().use(remarkHtml).use(adjustHeaders)) 
       .pipe(dateInPath()) 
       .pipe(addsrc('src/blog/index.jade')) 
       .pipe(postsToIndex('index.jade')) 
       .pipe(paginateIndexes()) 
       .pipe(jade({pretty: true, basedir: __dirname})) 
       .pipe(rename({ extname: '.html' })) 
       .pipe(gulp.dest('dist/blog')); 
}); 

但是,此设置实际上并不会输出任何索引页。

原来,在while循环中,您看到有逻辑使用Array.prototype.forEachArray.prototype.shift开始实施:

file.data.posts.forEach(function(post) { 
    page.push(post); 

    if (page.length === 10) { 
     var newFile = makePage(file, page, pageNumber); 

     pageFiles.push(newFile); 

     page = []; 
     pageNumber++; 
    } 
}); 

// Handle the last page which won't have 10 posts (and so will fail the above `if` test) 
if (page.length > 0) pageFiles.push(makePage(file, page, pageNumber)); 

这也实际上创建索引文件,但怪异file.data.posts值。如果我记得正确看起来像像每个页面的file.data.posts被设置为最后几个职位(即最终页面的值file.data.posts),但我不是积极的,这是发生了什么。

无论如何,我有点茫然。这对我来说似乎是真正简单的代码,并且我花了很多时间尝试调试。我注意到我也是其他几个插件的作者,它可能是或者,因为我在那些导致这个神秘错误的东西中做了一些愚蠢的事情.Gulpfile中的所有东西都在npm上发布,的stratic-paginate-indexes例外,可以随意看看其他模块,如果这就是问题的来自)

编辑:

修复了一些bug后在回答中指出,落实是现在这个:

while (file.data.posts.length > 0) { 
    page = file.data.posts.splice(0, 5); 

    var newFile = makePage(file, page, pageNumber); 
    pageFiles.push(newFile); 

    pageNumber++; 
} 

但是,由于某种原因,这导致无限系列的页面被输出,每个页面都具有与原始file.data.posts相同的前5个元素。几乎就像我使用Array.prototype.slice(除非显然我不是)。

问题是这一行:

var newFile = originalFile.clone(); 

不幸的是,为.clone()功能的乙烯基文档不正确(至少对于乙烯0.4.x,这是你与咕嘟咕嘟3得到什么)。文档指出.clone()做了一个深度克隆,但它实际上做了一个浅层克隆。使用black magic,你可以强制调用做深克隆:

var newFile = originalFile.clone(true); 

gulpjs/vinyl#125

对于索引文件,file.data.posts是乙烯基文件数组表示各个岗位

如果这是真的,那么你的问题是以下两行:

while (file.data.posts > 0) { 
    page = file.data.posts.splice(5); 

在第一行您正在比较阵列本身与0.您需要比较阵列的length,而不是:

while (file.data.posts.length > 0) { 

虽然这还不够。在第二行中,您只需一个参数即可调用Array.splice()。这将删除一切,但从file.data.posts前5个元素,所以file.data.posts.length将永远停留在5.繁荣。无限循环。

如果我理解你正确地要对数组的5组在这种情况下,第二行应该是这个分区:

page = file.data.posts.splice(0, 5); 

,将放在第5帖到page和删除他们从file.data.posts

+0

*叹*这是我在凌晨2点写代码所得到的结果。很好的接收!但是,这仍然不能解决我的问题 - 我将编辑新代码到我的问题中 – strugee

+0

无论您遇到什么问题,都无法用您的问题中的代码进行复制。你需要提供[mcve]。 –

+0

你能澄清你认为是缺失/不正确的?我很乐意编辑这个问题,但我不确定你在找什么 – strugee