2014-03-27 190 views
3

我已经开始使用Gulp JS,并且必须承认我发现它非常有用。如何使用Gulp Zip压缩zip文件

我需要执行的任务之一是将文件夹集合压缩成单独的zip文件,每个文件夹一个,然后将所有这些压缩文件压缩成一个zip文件。使用咕嘟咕嘟-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。不过,我接下来需要这些zip文件压缩成所谓的“Templates.zip”和我没有管理的一个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')); 

}); 

有谁知道这是可能的,或者什么我做错了?

回答

6

我也看到了问题,它似乎与某种方式的cwd选项有关。我会进一步调查。

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

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

  2. 捆绑zip无法正常工作的原因是,因为您指向/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流,最后到达压缩包流。通过这样做,您将拥有一个简单的数据流流程,读取一个磁盘,并在末尾写入一个磁盘,而不需要临时文件。

如果你需要它们是不同的任务,可以考虑使用一个函数来生成直到gulp.dest管道之前的步骤,并在所有的子任务上使用这个函数。

此外,总是尝试暗示您的异步任务by returning a stream, a promise or receiving a callback函数,并建议任务结束。

+1

他的解决方案可以工作 - 除非他没有从'zipModels'任务返回流。但是,您的解决方案更好,因为它可以避免临时文件。 – OverZealous

+0

谢谢,这太棒了。我已经使用了上面提供的代码,它的工作非常好。我也理解你提出的有关简单流和避免使用临时文件的观点。不幸的是,即使不使用临时文件,Gulp中的压缩过程也需要32秒才能运行,而使用调用7压缩文件的批处理文件需要大约7到9秒。我能想到的唯一解决方案是使用我的gulp.js文件中的gulp-exec来调用7 zip代替?尽管我接受其他建议。 – Robini

+0

我认为这与主要问题有点不同,可以考虑另外提出一个问题。但是如果你想提高性能,你可能需要调用'exec'。这没有问题。考虑为此插入一个插件,并且为'gulp.src'传递'{read:false}',因为你并不需要这些文件的内容,只需要拍一些。最好的方法是将内容传送到命令行实用程序,但[它不允许使用zip文件](http://sevenzip.sourceforge.jp/chm/cmdline/switches/stdin.htm),如果只能使用7zip的。 –