如何使用Gulp Zip压缩zip文件

3
我开始使用Gulp JS,并且必须承认我发现它非常有用。
我需要执行的任务之一是将一组文件夹压缩成单独的zip文件,每个文件夹一个zip文件,然后将所有这些zip文件压缩成一个单一的zip文件。使用Gulp-Zip,我已经成功实现了这一点:
var modelFolders = [
        'ELFH_Check',
        'ELFH_DDP',
        'ELFH_Free'
];

gulp.task('zipModels', function () {

        for (var i = 0; i < modelFolders.length; i++) {

            var model = modelFolders[i];

            gulp.src('**/*', {cwd: path.join(process.cwd(), '/built_templates/' + model) })
            .pipe(zip(model + '.zip'))
            .pipe(gulp.dest('./built_templates'));

        };

});

这个程序会生成ELFH_Check.zip、ELFH_DDP.zip和ELFH_Free.zip三个压缩文件。然而,我现在需要将这些压缩文件打包成一个名为“Templates.zip”的压缩文件,但是我还没有成功完成这个任务。
// zip up model files
gulp.task('zipTemplate', ['zipModels'], function () {  

        gulp.src('*.zip', {cwd: path.join(process.cwd(), './built_templates/') })
               .pipe(zip('Templates_.zip'))
               .pipe(gulp.dest('./built_templates'));

});

有人知道这是否可能或者我做错了什么吗?
1个回答

6

我也看到了这个问题,似乎与cwd选项有关。我会进一步调查。

在@OverZealous的评论之后,我进一步调查发现了两个问题:

  1. 正如他所说,你需要提示gulp等待依赖任务(zipModels)结束,通过从中返回一个流。由于你有多个流,可以使用event-stream.merge来返回一个捆绑流。

  2. 捆绑zip无法工作的原因是,你的cwd指向/built_templates/,第二个斜杠引起了一些问题。为了正常工作,你需要删除尾随斜杠,所以应该是path.join(process.cwd(), '/built_templates')

重要提示

无论如何,您应该避免使用临时文件。Gulp的哲学是尝试使用管道来避免IO。在这个方向上,您想要做的是剪切中间的dest步骤,merge流,zip它们,最后输出它们。

类似于这样:

var es = require('event-stream');

var modelFolders = [
    'ELFH_Check',
    'ELFH_DDP',
    'ELFH_Free'
];

gulp.task('zipModels', function () {
    var zips = [],
        modelZip;

    for (var i = 0; i < modelFolders.length; i++) {
        var model = modelFolders[i];

        modelZip = gulp.src('**/*', {cwd: path.join(process.cwd(), '/built_templates/' + model) })
          .pipe(zip(model + '.zip'));

        // notice we removed the dest step and store the zip stream (still in memory)
        zips.push(modelZip);
    };

    // we finally merge them (the zips), zip them again, and output.
    return es.merge.apply(null, zips)
        .pipe(zip('templates.zip'))
        .pipe(gulp.dest('./'));
});

根据您的文件夹名称(built_templates),似乎您还有其他任务会生成临时构建文件。最好不要保留这些文件。您应该将它们的流直接传输到ZIP流,最后传输到bundle-zip流。通过这样做,您将拥有一个简单的流程,一次磁盘读取和一个磁盘写入,没有临时文件。
如果您需要它们成为不同的任务,请考虑编写一个函数,该函数将生成流,直到gulp.dest管道之前的步骤,并在所有子任务上使用此函数。
此外,始终尝试提示异步任务通过返回streampromise或接收callback函数来建议任务结束

1
他的解决方案本来可以起作用——除非他没有从"zipModels"任务中返回流。然而,你的解决方案更好,因为它避免了临时文件。 - OverZealous
谢谢,这很棒。我已经使用了上面提供的代码,它运行得非常好。我也理解你提到的使用简单流和避免使用临时文件的要点。不幸的是,即使不使用临时文件,在Gulp中进行zip处理需要32秒才能运行,而使用调用7zip的批处理文件大约需要7到9秒。我唯一能想到的解决方案是在我的gulp.js文件中使用gulp-exec来调用7zip?但我也愿意听取其他建议。 - Robini
我认为这有点偏离主题,考虑另开一个问题。但是如果你想要性能提升,你可能需要调用 exec。这没有问题。不过最好写一个插件,并且在 gulp.src 中传递 {read: false},因为你并不需要文件的内容,只需要路径。最好的方法是将内容传输到命令行实用程序中,但是如果你只能使用 7Zip,它将不允许压缩文件。 - Caio Cunha
@Robini 最后一件事,如果您不一定需要使用7Zip,请尝试使用gulp-tar,或者包装 tar - Caio Cunha
谢谢CaioToOn,我同意,这确实是另一个问题。感谢您的建议,它非常有用。由于我的特殊情况,我可能会使用exec,因为我不能使用tar。 - Robini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接