2014-03-27 81 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的。 –