若效果不佳,參閱https://www.zybuluo.com/bornkiller/note/32907。javascript
前端開發近兩年工程化大幅飆升。隨着Nodejs
大放異彩,靜態文件處理再也不須要其餘語言輔助。主要的兩大工具即爲基於文件的grunt
,基於流的gulp
。簡單來講,若是須要的只是文件處理,gulp
絕對首選。若是是其餘依賴於文件的任務管理,例如測試(karma
,mocha
),推薦使用grunt
。前端
就插件開發難度而言,gulp遠低於grunt。若是你只關注如何處理文件,而不關注細節,那麼須要依賴Nodejs Transform stream
的實現。可使用官方推薦的through2
,但推薦使用through-gulp
。後者是基於前者,爲gulp插件編寫精簡優化重寫而來。千萬不要使用through
,這個包時間久遠,長時間沒有維護,並且部分mock實現的功能,到nodejs 0.10.x
已經原生支持。若是隻是想學習如何編寫gulp插件,through-gulp
更適合。through-gulp
: https://github.com/bornkiller/through-gulpthrough2
: https://github.com/rvagg/through2.gitthrough
: https://github.com/dominictarr/throughjava
// PLUGIN_NAME: sample var through = require('through-gulp'); function sample() { // creating a stream through which each file will pass var stream = through(function(file, encoding,callback) { // do whatever necessary to process the file if (file.isNull()) { } if (file.isBuffer()) { } if (file.isStream()) { } // just pipe data next, or just do nothing to process file later in flushFunction // never forget callback to indicate that the file has been processed. this.push(file); callback(); },function(callback) { // just pipe data next, just callback to indicate that the stream's over this.push(something); callback(); }); // returning the file stream return stream; }; // exporting the plugin module.exports = sample;
then use the plugin with gulpnode
var gulp = require('gulp'); var sample = require('sample'); gulp.task('sample', function() { return gulp.src(['source file']) .pipe(sample()) .pipe(gulp.dest('file destiny')) });
這個sample
是一個plugin的基本模板,一般關注的重點在於此處。git
if (file.isBuffer()) { //文件處理 }
須要特別注意的是,若是你須要處理的不一樣文件之間沒有任何依賴,在第一個函數函數內部處理完後,進行以下調用,便可將該文件的處理結果傳遞給下一個插件。這種狀況下,能夠缺省第二個參數flushFunction
。github
if (file.isBuffer()) { // 文件處理 var data = fileProcess(file); // 傳遞處理後數據給下一個插件 this.push(data); // 聲明該文件處理完畢 callback(); }
若是須要處理的不一樣文件之間存在依賴,例如文件合併,須要全部文件所有讀完以後再處理,那麼第一個參數transformFunction
將每次傳遞進來的數據保存在內存中(絕對不要在這裏調用this.push()
方法),第二個參數flushFunction
統一作處理後,再傳遞給下一個插件。gulp
// transformFunction var fileStorage = []; if (file.isBuffer()) { // 文件處理 var data = fileProcess(file); // 保存傳遞進來的數據 fileStorage.push(data); // 聲明該文件處理完畢 callback(); }
// flushFunction function(callback) { var result = ''; var final = null; fileStorage.foreach(function(file, key) { result += file.contents.toString(); }) final = new Buffer(result); this.push(final); callback(); }
就插件編寫的角度而言,through-gulp
能夠把你從through2
晦澀的文檔中解救出來,不過有一個不幸的地方,在插件開發的單元測試中,經常使用的assert-stream
是基於through2
的,可是不影響大局。近期考慮本身從新實現一個版本,基於through-gulp
,目的在於爲gulp插件編寫下降難度。同時through-gulp
目前徹底可用,歡迎改造。https://github.com/bornkiller/through-gulp。dom