# 將 buffer 變為 stream (內存中的內容)
有時候,你會需要這樣一個 stream,它們的內容保存在一個變量中,而不是在一個實際的文件中。換言之,怎么不使用 `gulp.src()` 而創建一個 'gulp' stream。
我們來舉一個例子,我們擁有一個包含 js 庫文件的目錄,以及一個包含一些模塊的不同版本文件的目錄。編譯的目標是為每個版本創建一個 js 文件,其中包含所有庫文件以及相應版本的模塊文件拼接后的結果。
邏輯上我們將把這個拆分為如下步驟:
* 載入庫文件
* 拼接庫文件的內容
* 載入不同版本的文件
* 對于每個版本的文件,將其和庫文件的內容拼接
* 對于每個版本的文件,將結果輸出到一個文件
想象如下的文件結構:
```
├── libs
│?? ├── lib1.js
│?? └── lib2.js
└── versions
├── version.1.js
└── version.2.js
```
你應該要得到這樣的結果:
```
└── output
├── version.1.complete.js # lib1.js + lib2.js + version.1.js
└── version.2.complete.js # lib1.js + lib2.js + version.2.js
```
一個簡單的模塊化處理方式將會像下面這樣:
```
var gulp = require('gulp');
var runSequence = require('run-sequence');
var source = require('vinyl-source-stream');
var vinylBuffer = require('vinyl-buffer');
var tap = require('gulp-tap');
var concat = require('gulp-concat');
var size = require('gulp-size');
var path = require('path');
var es = require('event-stream');
var memory = {}; // 我們會將 assets 保存到內存中
// 載入內存中文件內容的任務
gulp.task('load-lib-files', function() {
// 從磁盤中讀取庫文件
return gulp.src('src/libs/*.js')
// 將所有庫文件拼接到一起
.pipe(concat('libs.concat.js'))
// 接入 stream 來獲取每個文件的數據
.pipe(tap(function(file) {
// 保存文件的內容到內存
memory[path.basename(file.path)] = file.contents.toString();
}));
});
gulp.task('load-versions', function() {
memory.versions = {};
// 從磁盤中讀取文件
return gulp.src('src/versions/version.*.js')
// 接入 stream 來獲取每個文件的數據
.pipe( tap(function(file) {
// 在 assets 中保存文件的內容
memory.versions[path.basename(file.path)] = file.contents.toString();
}));
});
gulp.task('write-versions', function() {
// 我們將不容版本的文件的名字保存到一個數組中
var availableVersions = Object.keys(memory.versions);
// 我們創建一個數組來保存所有的 stream 的 promise
var streams = [];
availableVersions.forEach(function(v) {
// 以一個假文件名創建一個新的 stream
var stream = source('final.' + v);
// 從拼接后的文件中讀取數據
var fileContents = memory['libs.concat.js'] +
// 增加版本文件的數據
'\n' + memory.versions[v];
streams.push(stream);
// 將文件的內容寫入 stream
stream.write(fileContents);
process.nextTick(function() {
// 在下一次處理循環中結束 stream
stream.end();
});
stream
// 轉換原始數據到 stream 中去,到一個 vinyl 對象/文件
.pipe(vinylBuffer())
//.pipe(tap(function(file) { /* 這里可以做一些對文件內容的處理操作 */ }))
.pipe(gulp.dest('output'));
});
return es.merge.apply(this, streams);
});
//============================================ 我們的主任務
gulp.task('default', function(taskDone) {
runSequence(
['load-lib-files', 'load-versions'], // 并行載入文件
'write-versions', // 一旦所有資源進入內存便可以做寫入操作了
taskDone // 完成
);
});
//============================================ 我們的監控任務
// 只在運行完 'default' 任務后運行,
// 這樣所有的資源都已經在內存中了
gulp.task('watch', ['default'], function() {
gulp.watch('./src/libs/*.js', function() {
runSequence(
'load-lib-files', // 我們只需要載入更改過的文件
'write-versions'
);
});
gulp.watch('./src/versions/*.js', function() {
runSequence(
'load-versions', // 我們只需要載入更改過的文件
'write-versions'
);
});
});
```
- gulp 中文文檔
- 入門指南
- gulp API 文檔
- 編寫插件
- 指導
- 使用 buffer
- 使用 Stream 處理
- 測試
- FAQ
- gulp 技巧集
- 整合 streams 來處理錯誤
- 刪除文件和文件夾
- 使用 watchify 加速 browserify 編譯
- 增量編譯打包,包括處理整所涉及的所有文件
- 將 buffer 變為 stream (內存中的內容)
- 在 gulp 中運行 Mocha 測試
- 僅僅傳遞更改過的文件
- 從命令行傳遞參數
- 只重新編譯被更改過的文件
- 每個文件夾生成單獨一個文件
- 串行方式運行任務,亦即,任務依賴
- 擁有實時重載(live-reloading)和 CSS 注入的服務器
- 通過 stream 工廠來共享 stream
- 指定一個新的 cwd (當前工作目錄)
- 分離任務到多個文件中
- 使用外部配置文件
- 在一個任務中使用多個文件來源
- Browserify + Uglify2 和 sourcemaps
- Browserify + Globs
- 同時輸出一個壓縮過和一個未壓縮版本的文件
- 改變版本號以及創建一個 git tag
- Swig 以及 YAML front-matter 模板