跳到主要内容

从缓冲区(内存内容)创建流

有时你可能需要使用内容存储在变量中而不是物理文件中的文件来开始一个流。换句话说,如何在不使用 gulp.src() 的情况下启动一个 'gulp' 流。

例如,假设我们有一个包含 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 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 = {}; // 我们将资源保存在内存中

// 将文件内容加载到内存中的任务
gulp.task('load-lib-files', function() {
// 从磁盘读取库文件
return gulp.src('src/libs/*.js')
// 将所有库文件连接为一个
.pipe(concat('libs.concat.js'))
// 接入流以获取每个文件的数据
.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')
// 接入流以获取每个文件的数据
.pipe( tap(function(file) {
// 将文件内容保存在资源中
memory.versions[path.basename(file.path)] = file.contents.toString();
}));
});

gulp.task('write-versions', function() {
// 我们将所有不同的版本文件名存储在一个数组中
var availableVersions = Object.keys(memory.versions);
// 我们创建一个数组来存储所有的流承诺
var streams = [];

availableVersions.forEach(function(v) {
// 使用假文件名创建一个新流
var stream = source('final.' + v);

var streamEnd = stream;

// 我们从连接的库中加载数据
var fileContents = memory['libs.concat.js'] +
// 我们添加版本的数据
'\n' + memory.versions[v];

// 将文件内容写入流
stream.write(fileContents);

process.nextTick(function() {
// 在下一个进程周期中,结束流
stream.end();
});

streamEnd = streamEnd
// 将流中的原始数据转换为 vinyl 对象/文件
.pipe(vinylBuffer())
//.pipe(tap(function(file) { /* 在这里对文件内容做一些处理 */ }))
.pipe(gulp.dest('output'));

// 添加流的结束,否则任务会在所有处理完成之前就结束
streams.push(streamEnd);

});

return es.merge.apply(this, streams);
});

//============================================ 我们的主要任务
gulp.task('default', gulp.series(
// 并行加载文件
gulp.parallel('load-lib-files', 'load-versions'),
// 一旦所有资源都在内存中,就准备好写入
'write-versions'
)
);

//============================================ 我们的监视任务
// 只有在运行 'default' 一次之后才开始监视,这样所有资源
// 都已经在内存中了
gulp.task('watch', gulp.series(
'default',
function() {
gulp.watch('./src/libs/*.js', gulp.series(
'load-lib-files',
'write-versions'
));

gulp.watch('./src/versions/*.js', gulp.series(
'load-lib-files',
'write-versions'
));
}
));