使用Gulp迭代目录?

时间:2014-03-03 14:56:57

标签: javascript 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

...我想要两个文件:/js/feature1/feature1.min.js/js/feature2/feature2.min.js,其中第一个包含前4个文件,第二个包含最后2个文件。

这可能,或者我是否必须手动将这些目录添加到清单?实际迭代/js/中的所有目录真的很不错。

感谢您提供任何帮助。

-Nate

编辑:应该注意的是,我不仅有2个目录,但我有很多(可能是10-20个),所以我真的不想为每个目录编写任务。我想以相同的方式处理每个目录:获取其中的所有JS(以及任何子目录)并将其编译为基于特征的缩小JS文件。

5 个答案:

答案 0 :(得分:44)

这是官方配方:Generating a file per folder

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

答案 1 :(得分:16)

您可以使用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);
});

答案 2 :(得分:4)

我正在努力了解流如何在节点中工作。 我为您做了一个简单的示例,介绍了如何使流过滤文件夹并为它们启动新的给定流。

'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自定义流一样。

尝试一下,让我知道它是否适合你。

答案 3 :(得分:0)

首先,安装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

答案 4 :(得分:0)

我在使用gulp配方时遇到了麻烦,也许是因为我使用的是gulp 4和/或因为我还是不想合并所有文件夹的输出。 我调整了配方以在每个文件夹中生成(但不运行)匿名函数,并返回函数数组,以使它们能够由gulp.parallel处理-以某种方式生成的函数数是可变的。这种方法的关键是:

  1. 每个生成的函数都必须是一个函数或组合(而不是流)。就我而言,每个生成的函数都是一个序列组成,因为在构建每个模块文件夹时我要做很多事情。

  2. 函数数组需要使用javascript apply()传递到我的构建任务中,因为在我的案例中,数组的每个成员都需要转换为gulp.parallel的参数。 我的函数摘录生成了函数数组:

    function getModuleFunctions() {
        //Get list of folders as per recipe above - in my case an array named modules
    
        //For each module return a function or composition (gulp.series in this case).
        return modules.map(function (m) {
            var moduleDest = env.folder + 'modules/' + m;
            return gulp.series(
                //Illustrative functions... all must return a stream or call callback but you can have as many functions or compositions (gulp.series or gulp.parallel) as desired
                function () {
                    return gulp.src('modules/' + m + '/img/*', { buffer: false })
                        .pipe(gulp.dest(moduleDest + '/img'));
                },
                function (done) {
                    console.log('In my function');
                    done();
                }
            );
        });
    }
    
    //Illustrative build task, running two named tasks then processing all modules generated above in parallel as dynamic arguments to gulp.parallel, the gulp 4 way
    gulp.task('build', gulp.series('clean', 'test', gulp.parallel.apply(gulp.parallel, getModuleFunctions())));  
    

    `