Подтвердить что ты не робот

Итерирование по каталогам с помощью Gulp?

Я новичок в gulp, но мне интересно, можно ли его итерации по каталогам в задаче gulp.

Вот что я имею в виду, я знаю, что много учебников/демонстраций демонстрируют обработку кучи файлов JavaScript с использованием чего-то типа "**/*. js", а затем они скомпилируют его в один файл 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

... И я хочу два файла: /js/feature1/feature1.min.js и /js/feature2/feature2.min.js, где первый содержит первые 4 файла, а второй содержит последние 2 файла.

Возможно ли это, или мне придется вручную добавить эти каталоги в манифест? Было бы очень полезно прагматически перебирать все каталоги в /js/.

Спасибо за любую помощь, которую вы можете мне дать.

-Nate

Изменить: Следует отметить, что у меня есть не только 2 каталога, но у меня много (может быть, 10-20), поэтому я действительно не хочу писать задачу для каждой директории, Я хочу обрабатывать каждый каталог таким же образом: получить все JS внутри него (и любые подкаталоги) и скомпилировать его в основанный на характеристиках JS файл.

4b9b3361

Ответ 1

Вот официальный рецепт этого: Создание файла для каждой папки

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

Ответ 2

Вы можете использовать glob, чтобы получить список каталогов и перебрать их, используя gulp.src для создания отдельного конвейера для каждой функции. Затем вы можете вернуть обещание, которое разрешено, если все ваши потоки имеют end ed.

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

Ответ 3

Я пытаюсь понять, как работают потоки в node. Я сделал простой пример для вас, как сделать поток для фильтрации папок и запустить для них новый поток.

'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 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

Сначала установите gulp-concat и gulp-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