代码之家  ›  专栏  ›  技术社区  ›  strugee

Gulp插件:将一个乙烯基文件拆分为多个文件不能正确划分数据

  •  0
  • strugee  · 技术社区  · 9 年前

    我有一个吞咽插件, 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 是一个乙烯基文件数组,表示要包含在渲染页面上的各个帖子。这是我正在使用的吞咽任务:

    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.forEach Array.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上,但明显的例外是 分层分页索引 ,因此,如果这是问题的根源,请随意查看其他模块。)

    编辑:

    修复了答案中指出的一些错误后,现在的实现如下:

    while (file.data.posts.length > 0) {
        page = file.data.posts.splice(0, 5);
    
        var newFile = makePage(file, page, pageNumber);
        pageFiles.push(newFile);
    
        pageNumber++;
    }
    

    然而,由于某种原因,这会导致输出无限系列的页面,每个页面都具有原始页面的前5个元素 file.data.posts .就像我用的一样 Array.prototype.slice (显然我不是)。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Sven Schoenung    9 年前

    对于索引文件, file.data.posts 是一个表示单个帖子的乙烯基文件数组

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

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

    在第一行中,您正在比较 数组本身 与0。您需要比较 length 而不是数组的:

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

    但这还不够。在第二行,你在打电话 Array.splice() 只有一个论点。这将删除除前5个元素以外的所有元素 file.data.posts 所以 file.data.posts.length 它将永远保持在5.繁荣。无限循环。

    如果我理解正确,您希望将数组划分为5组。在这种情况下,第二行应该是:

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

    这将使前5个职位 page 并将它们从 file.data.posts .

        2
  •  0
  •   strugee    9 年前

    这条线的问题在于:

    var newFile = originalFile.clone();
    

    不幸的是 .clone() 函数不正确(至少对于乙烯基0.4.x,这是您使用Gulp 3得到的)。文件指出: .clone() 做深度克隆,但实际上做的是浅层克隆。使用 black magic ,您可以强制调用执行深度克隆:

    var newFile = originalFile.clone(true);
    

    看见 gulpjs/vinyl#125 .