是否有一些gulp插件可以让它执行静态站点生成器的功能?

是否有一些gulp插件可以让它执行静态站点生成器的功能?,gulp,static-site,Gulp,Static Site,我用过很多静态站点生成器,但是gulp是一个更好的方法,因为它是模块化的。我想知道是否有一个插件可以执行静态站点生成器的一些功能。在我看来,所缺少的只是将目录中的文件转换为json数据结构,以便在站点菜单中使用。是的,您可以在gulp中进行静态生成 你可能需要比你想象的更少的插件。计数可能会四舍五入到零 考虑一下,在不使用插件的情况下,您可以做些什么: var gulp = require('gulp'), browserify = require('browserify'); gul

我用过很多静态站点生成器,但是gulp是一个更好的方法,因为它是模块化的。我想知道是否有一个插件可以执行静态站点生成器的一些功能。在我看来,所缺少的只是将目录中的文件转换为json数据结构,以便在站点菜单中使用。

是的,您可以在gulp中进行静态生成

你可能需要比你想象的更少的插件。计数可能会四舍五入到零

考虑一下,在不使用插件的情况下,您可以做些什么:

var gulp = require('gulp'),
    browserify = require('browserify');

gulp.task('browserify', function(callback) {
    browserify('app.js').bundle()
        .pipe(fs.createWriteStream('dist/app.js')
        .on('close', callback); // why? read on...
});
。他们将一些原始模块改编为在
gulp.src
gulp.dest
之间使用的乙烯基对象流,但乙烯基对象流不是强制性的

需要模块X为您执行部分静态生成吗?将
callback
作为任务函数的参数,并将其与参数一起传递给X。通常情况下,它只是一行代码:
需要
-使用插件只会使代码变长

即使对于工作流程中最好描述为“读取所有内容,在内存中处理,然后只写一次”的部分,您也可以使用来转换乙烯基对象或将其删除。吞下插件(或者更糟糕的是,通过插件)是最后的选择

var gulp = require('gulp'),
    filter = require('gulp-filter'),
    through2 = require('through2');

gulp.task('generate-assets', function() {
    return gulp.src('path/to/your/content/and/templates/**')
               .pipe(filter(shouldFileSurvive))
               .pipe(through2.obj(makeFileDifferent))
               .pipe(gulp.dest('dist/'));
});
注意:如果您不回电话,则必须返回最终
管道的结果。否则,gulp会认为您的任务是同步的,而不是在启动依赖任务之前等待


如果最终管道返回的是正常流,而不是
gulp.dest
,则执行回调(请参见第一个示例),直到到达。

如果您只想生成一个.json结构并将其添加到带有gulp的文件中,可以通过以下几种方法之一执行此操作。前两种方法使用纯吞咽技术:

  • 您可以使用
    到h2
    编写流插件,这基本上需要一次构建一个文件的数据结构,然后在第二次操作中,将在末尾创建(即
    推送()
    队列()
    )一个文件

  • 您可以使用管道将文件
    .reduce()
    还原为数据结构,然后将结果
    .map()
    映射为文件,或者对原始流执行
    .merge()

在这两种情况下,您都需要生成新的
乙烯基
文件以具有适当的
.base
.path
,因为您正在创建的文件尚不存在,所以您的插件实际上不知道该文件。因此,您的代码必须组成一个虚假的绝对路径,以便
gulp.dest()
将其放在正确的位置

第三种方法是编写一个插件,其外观如下:

function generate_json(files, smith, done) {
    var menu = {};
    Object.keys(files).forEach(function(path) {
        var file = files[path];
        if (path.slice(-5)===".html") {
            menu[path] = ... // whatever you want to store about `file`
        }
    });
    files["path/to/menu.json"] = { contents: new Buffer(JSON.stringify(menu)) };
    done();
}
虽然不比其他方法所需的代码短很多,但为了正确地执行,您需要理解的代码要少得多。只要确保如果有错误,您可以调用
done(err)
来传递错误

如果您想将此插件与一条吞咽管道相结合,您可以使用以下方法将其打包:

的确,Gulp比Metalsmith有某些优势。遗憾的是,编写插件的简易性并不是其中之一。从一个Gulp插件创建新文件比它应该的要难,正确的错误处理也是如此。流式传输方法和静态站点需要跨文件操作的特性之间也存在强烈的阻抗不匹配

例如,如果您想在创建后将菜单嵌入到每个.html页面中,您需要一个更复杂的Gulp插件,因为当您的插件“看到”所有文件时,它们会“顺流”,否则您必须保留它们,然后在完成后再将它们流出来。在Metalsmith插件中,您只需在生成菜单后添加第二个循环,再次返回文件以将数据插入到位。你不需要做任何事情来传递你没有做任何事情的文件

对于这类任务,Metalsmith插件API明显优于Gulp。但是对于可以单独处理流文件的任务,可以使用现有的Gulp插件

基本上,Metalsmith实际上是静态站点生成器的一部分,而Gulp是流式构建系统的一部分。你可以使用Gulpsmith将两者的优点结合起来


(顺便说一句,根据您的实际任务,您可能会发现一些现有的Metalsmith插件可以完成全部或部分任务。例如,
Metalsmith集合
插件为匹配特定模式的文件创建索引,还有一个
Metalsmith标题
可以将HTML标题提取到标题属性,等等。)我一直在写这样一个插件,它就在这里。看看另外两个答案,我会说它的功能介于香草口味和
gulpsmith
之间

吞下文件树

其主要功能实际上是计算树状数据结构,这是由。它逐渐地建立一棵树,直到流结束。然后,每个文件(乙烯基对象)都使用
.tree
属性重新提交

查看以获取有关该数据结构的更多信息

吞下静态站点

这个插件获取一个HTML文件流,通过
gulpfiletree
将它们发送到一个jade模板中,该模板添加了一个带有目录树菜单和文件内容的基本布局

看,看,这里是主管道。 (正如你所看到的,它不是最漂亮的,但还行。降价转换必须被删除,因为它可以在插件之外的地方进行。其他东西可能也有相同的理由…)

Q:这与
gulpsmith
有什么关系?

Gulpsmith看起来绝对是强大和完整的,如果我在初始化时知道它,我可能会使用它
gulp.src(...)
.pipe( things() )
.pipe( gulpsmith().use(generate_json) )
.pipe( other_stuff() )
.pipe( gulp.dest(...);