web-dev-qa-db-ja.com

Gulpでディレクトリを繰り返し処理しますか?

gulp が初めてですが、gulpタスクでディレクトリを反復処理することが可能かどうか疑問に思っています。

私が言いたいのは、多くのチュートリアル/デモが「**/*。js」のようなものを使用して一連のJavaScriptファイルを処理し、それを単一のJavaScriptファイルにコンパイルすることを示していることです。しかし、一連のディレクトリを反復処理し、各ディレクトリを独自のJSファイルにコンパイルしたいと思います。

たとえば、次のようなファイル構造があります。

/js/feature1/something.js
/js/feature1/else.js
/js/feature1/foo/bar.js
/js/feature1/foo/bar2.js
/js/feature2/another-thing.js
/js/feature2/yet-again.js

...そして、2つのファイルが必要です:/js/feature1/feature1.min.js/js/feature2/feature2.min.js最初のファイルには最初の4つのファイルが含まれ、2番目のファイルには最後の2つのファイルが含まれます。

これは可能ですか、またはそれらのディレクトリをマニフェストに手動で追加する必要がありますか? /js/内のすべてのディレクトリを実際に反復処理することは本当に素晴らしいことです。

助けてくれてありがとう。

-ネイト

編集:2つのディレクトリしか持っていないことに注意する必要がありますが、多くのディレクトリ(おそらく10〜20)があるので、実際には各ディレクトリのタスクを書きたい。各ディレクトリを同じ方法で処理します。その中のすべてのJS(および任意のサブディレクトリ)を取得し、機能ベースの縮小されたJSファイルにコンパイルします。

33
Nathan Rutman

これには公式のレシピがあります: フォルダーごとにファイルを生成する

var fs = require('fs');
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');

var scriptsPath = 'src/scripts';

function getFolders(dir) {
    return fs.readdirSync(dir)
      .filter(function(file) {
        return fs.statSync(path.join(dir, file)).isDirectory();
      });
}

gulp.task('scripts', function() {
   var folders = getFolders(scriptsPath);

   var tasks = folders.map(function(folder) {
      return gulp.src(path.join(scriptsPath, folder, '/**/*.js'))
        // concat into foldername.js
        .pipe(concat(folder + '.js'))
        // write to output
        .pipe(gulp.dest(scriptsPath)) 
        // minify
        .pipe(uglify())    
        // rename to folder.min.js
        .pipe(rename(folder + '.min.js')) 
        // write to output again
        .pipe(gulp.dest(scriptsPath));    
   });

   // process all remaining files in scriptsPath root into main.js and main.min.js files
   var root = gulp.src(path.join(scriptsPath, '/*.js'))
        .pipe(concat('main.js'))
        .pipe(gulp.dest(scriptsPath))
        .pipe(uglify())
        .pipe(rename('main.min.js'))
        .pipe(gulp.dest(scriptsPath));

   return merge(tasks, root);
});
45
Ghidello

globを使用してディレクトリのリストを取得し、gulp.srcを使用してディレクトリを反復処理し、機能ごとに個別のパイプラインを作成できます。その後、すべてのストリームにendedがあるときに解決されるpromiseを返すことができます。

var fs = require('fs');
var Q = require('q');
var gulp = require('gulp');
var glob = require('glob');

gulp.task('minify-features', function() {
  var promises = [];

  glob.sync('/js/features/*').forEach(function(filePath) {
    if (fs.statSync(filePath).isDirectory()) {
      var defer = Q.defer();
      var pipeline = gulp.src(filePath + '/**/*.js')
        .pipe(uglify())
        .pipe(concat(path.basename(filePath) + '.min.js'))
        .pipe(gulp.dest(filePath));
      pipeline.on('end', function() {
        defer.resolve();
      });
      promises.Push(defer.promise);
    }
  });

  return Q.all(promises);
});
16
Ben

ノードでストリームがどのように機能するかを取得しようとしています。簡単な例を作成しました。ストリームを作成してフォルダーをフィルター処理し、フォルダーに対して新しい指定されたストリームを開始する方法について説明しました。

'use strict';

var gulp             = require('gulp'),
    es               = require('event-stream'),
    log              = require('consologger');

// make a simple 'stream' that prints the path of whatever file it gets into
var printFileNames = function(){

    return es.map(function(data, cb){

        log.data(data.path);
        cb(null, data);
    });
};

// make a stream that identifies if the given 'file' is a directory, and if so
// it pipelines it with the stream given
var forEachFolder = function(stream){

    return es.map(function(data, cb){

        if(data.isDirectory()){

            var pathToPass = data.path+'/*.*';  // change it to *.js if you want only js files for example

            log.info('Piping files found in '+pathToPass);

            if(stream !== undefined){
                gulp.src([pathToPass])
                .pipe(stream());
            }
        }

        cb(null, data);
    });
};


// let's make a dummy task to test our streams
gulp.task('dummy', function(){
    // load some folder with some subfolders inside
    gulp.src('js/*')
    .pipe(forEachFolder(printFileNames));
    // we should see all the file paths printed in the terminal
});

したがって、あなたの場合、フォルダ内のファイルで作成したいものを使ってストリームを作成し(それらを縮小して連結するなど)、このストリームのインスタンスを作成したforEachFolderストリームに渡すことができます。 printFileNamesカスタムストリームで行うように。

それを試してみて、それがあなたのために働くかどうか私に知らせてください。

4
AntouanK

まず、 gulp-concatgulp-uglify をインストールします。

$ npm install gulp-concat
$ npm install gulp-uglify

次に、次のようなことをします:

//task for building feature1
gulp.task('minify-feature1', function() {
 return gulp.src('/js/feature1/*')
  .pipe(uglify()) //minify feature1 stuff
  .pipe(concat('feature1.min.js')) //concat into single file
  .pipe(gulp.dest('/js/feature1')); //output to dir
});

//task for building feature2
gulp.task('minify-feature2', function() { //do the same for feature2
 return gulp.src('/js/feature2/*')
  .pipe(uglify())
  .pipe(concat('feature2.min.js'))
  .pipe(gulp.dest('/js/feature2'));
});

//generic task for minifying features
gulp.task('minify-features', ['minify-feature1', 'minify-feature2']);

これで、CLIからすべてを縮小するために必要なことは次のとおりです。

$ gulp minify-features
0
adamb