バッファからストリームを作成(メモリ・コンテンツ)

時に、あなたは内容が固定化されないファイルから、ストリームを開始しなければいけないケースに遭遇するかもしれません。 言い換えると、gulp.src()を使用しないで'gulp'ストリームを始めるにはどのようにしたら良いか?ということになります。

jsのライブラリファイルを入れるディレクトリと、幾つかのモジュールのバージョンを持つ別のディレクトリがあると仮定しましょう。 ビルドの対象となるのは各バージョンのjsファイルの作成であり、 これには全てのlibsとそのバージョンのモジュールが連結されたものが含まれます。

必然的に、これは次のように解決されることになります。

  • libファイルの読み込み
  • そのlibファイルの内容を連結
  • バージョンファイルを読み込み
  • 各バージョンのファイルのために、libの内容とバージョンファイルの内容を連結
  • その結果を各バージョンのファイルとして出力

下記のファイル構成があると仮定します。

├── 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 = {}; // メモリ内にアセットを保持するためのもの

// メモリ内のファイル内容を読み込むタスク
gulp.task('load-lib-files', function() {
  // ディスクからlibファイルを読み込み
  return gulp.src('src/libs/*.js')
  // 全てのlibファイルを1つのファイルに連結
  .pipe(concat('libs.concat.js'))
  // 各ファイルのデータを取得し、ストリームへtap
  // (訳注: tapの詳細は、gulp-tapプラグインを調べてください)
  .pipe(tap(function(file) {
    // メモリ内にファイルの内容を保存
    memory[path.basename(file.path)] = file.contents.toString();
  }));
});

gulp.task('load-versions', function() {
  memory.versions = {};
  // ディスクからversionファイルを読み込み
  return gulp.src('src/versions/version.*.js')
  // 各ファイルデータを取得し、ストリームへtap
  .pipe( tap(function(file) {
    // ファイルの内容をアセット内に保存
    memory.versions[path.basename(file.path)] = file.contents.toString();
  }));
});

gulp.task('write-versions', function() {
  // 配列内の異なるバージョンのファイル名を全て格納
  var availableVersions = Object.keys(memory.versions);
  // 全てのストリームのpromiseを格納する配列を作成
  var streams = [];

  availableVersions.forEach(function(v) {
    // ファイル名を偽造して新しいストリームを作成
    var stream = source('final.' + v);
    // 連結したlibsからデータを読み込み
    var fileContents = memory['libs.concat.js'] +
      // バージョンのデータを追加
      '\n' + memory.versions[v];

    streams.push(stream);

    // ストリームにファイル内容を書き込み
    stream.write(fileContents);

    process.nextTick(function() {
      // 次のプロセスサイクルで、ストリームを終了
      stream.end();
    });

    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'
    );
  });
});

 Back to top

© 2010 - 2017 STUDIO KINGDOM