web-dev-qa-db-fra.com

Vous parcourez les répertoires avec Gulp?

Je suis nouveau dans gulp , mais je me demande s'il est possible de parcourir les répertoires dans une tâche gulp.

Voici ce que je veux dire, je sais que de nombreux didacticiels/démos montrent le traitement d'un tas de fichiers JavaScript en utilisant quelque chose comme "**/*. Js", puis ils le compilent en un seul fichier JavaScript. Mais je veux parcourir un ensemble de répertoires et compiler chaque répertoire dans son propre fichier JS.

Par exemple, j'ai une structure de fichiers comme:

/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

... Et je veux deux fichiers: /js/feature1/feature1.min.js et /js/feature2/feature2.min.js où le premier contient les 4 premiers fichiers et le second les 2 derniers fichiers.

Est-ce possible, ou vais-je devoir ajouter manuellement ces répertoires à un manifeste? Ce serait vraiment bien d'itérer de manière pragmatique tous les répertoires de /js/.

Merci pour toute l'aide que tu peux m'apporter.

-Nate

Edit: Il convient de noter que je n'ai pas seulement 2 répertoires, mais j'en ai beaucoup (peut-être 10-20) donc je n'ai pas vraiment souhaitez écrire une tâche pour chaque répertoire. Je veux gérer chaque répertoire de la même manière: obtenir tout le JS à l'intérieur (et tous les sous-répertoires) et le compiler dans un fichier JS minifié basé sur les fonctionnalités.

33
Nathan Rutman

Il y a une recette officielle pour cela: Génération d'un fichier par dossier

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

Vous pouvez utiliser glob pour obtenir une liste des répertoires et les parcourir, en utilisant gulp.src pour créer un pipeline distinct pour chaque entité. Vous pouvez ensuite renvoyer une promesse qui est résolue lorsque tous vos flux ont ended.

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

J'essaie moi-même de savoir comment les flux fonctionnent dans le nœud. J'ai fait un exemple simple pour vous, sur la façon de créer un flux pour filtrer les dossiers et démarrer un nouveau flux donné pour eux.

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

Donc, dans votre cas, vous pouvez créer un flux avec tout ce que vous voulez créer avec les fichiers d'un dossier (comme les réduire et les concaténer), puis passer une instance de ce flux au flux forEachFolder que j'ai créé. Comme je le fais avec le flux personnalisé printFileNames.

Essayez-le et faites-moi savoir si cela fonctionne pour vous.

4
AntouanK

Tout d'abord, installez gulp-concat & gulp-uglify .

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

Ensuite, faites quelque chose comme:

//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']);

Maintenant, tout ce que vous avez à faire pour tout réduire à partir de la CLI est:

$ gulp minify-features
0
adamb