web-dev-qa-db-fra.com

Tâche Gulp avec une source différente en fonction des arguments

Je veux accomplir quelque chose de simple en utilisant une gorgée. Je veux écrire une méthode générique pour déplacer des fichiers dans un répertoire de sortie à partir d'un répertoire source particulier.

prétendre que nous avons quelque chose comme ça 

var args = require('yargs');
function transform-move-jsx-Development() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_development));
};

function transform-move-jsx-Production() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_production));
};

gulp.task('transform-move-jsx-Development', transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);

Les deux tâches: transformation-move-jsx-Production et transform-move-jsx-Development sont identiques, à l'exception du répertoire de sortie. Je veux le rendre plus DRY (ne vous répétez pas). Je devrais être capable de faire une seule méthode qui peut utiliser un paramètre yarg ou quelque chose de bien? Dans cet exemple suivant, je prétends pouvoir passer le chemin comme argument

Alors j'essaie quelque chose comme ça en utilisant yargs

var args = require('yargs');

function transform-move-jsx() 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(args.outputDirectory));
};

gulp.task('dev', ['transform-move-jsx']);

Cependant, cela nécessite maintenant d'ajouter des arguments à l'appel gulp sur la ligne de commande.

gulp dev --"path to output, etc."

Cela est évidemment moins gérable car nous appelons de plus en plus de tâches gulp à l'intérieur de la tâche dev gulp. Et serait désordonné de toute façon, car nous n'aurions pas besoin de connaître un détail d'implémentation tel que la structure du répertoire de sortie lorsque nous exécutons gulp dev

Je pourrais plutôt faire quelque chose comme ça:

function transform-move-jsx(destination) 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(destination));
};

function transform-move-jsx-Development() 
{
    transform-move-jsx("./output/development/");
};

function transform-move-jsx-Production() 
{
    transform-move-jsx("./output/production/");
};

gulp.task('transform-move-jsx-Development',transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod',  transform-move-jsx-Production);
gulp.task('dev',  transform-move-jsx-Development);

Cela semble meilleur dans la mesure où il est plus flexible, mais à présent, mon fichier gulpfile est jonché de plusieurs fonctions inutiles.

Y a-t-il un meilleur moyen?

27
jth41

Vous avez été sur la bonne voie avec votre deuxième essai, juste besoin d'utiliser un peu de SEC et fermetures

function createTransformTaskClosure (destination) {
    return function () {
        return gulp.src(config.sourceJSX)
                   .pipe(gulp.dest(destination));
    };
}

gulp.task('dev', createTransformTaskClosure(config.output_development));
gulp.task('prod', createTransformTaskClosure(config.output_production));
25
Dennis Baizulin

J'ai fait quelque chose de similaire en utilisant une seule fonction:

function getDest(folder){
    var folder = folder || '';
    var newDest;
    if (args.build){
        newDest = config.build.home + folder;
    }
    if (args.temp){
        newDest = config.temp.home + folder;
    }
    return newDest;
}

Ensuite, quand j'appellerais gulp.dest ():

.pipe(gulp.dest(getDest())) // defaults to ./ directory

Ou si je voulais un sous-dossier:

.pipe(gulp.dest(getDest(config.css)))

Mon fichier de configuration avait simplement des chemins, à savoir:

config = {
   css: '/css/',
   home: './',
   js: '/js/'
}

J'espère que cela pourra aider.

1
MaxRocket

Que diriez-vous de quelque chose comme ce qui suit: 

var args = require('yargs');
function transform-move-jsx(destination) {
    return function(){
        return gulp.src(config.sourceJSX)
                   .pipe(react, browserify, etc....)
                   .pipe(gulp.dest(destination));
    }
};

gulp.task('transform-move-jsx-Development', transform-move-jsx(config.output_development));
gulp.task('transform-move-jsx-Production', transform-move-jsx(config.output_production));

gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);  
0
ordepim

Un peu tard pour la fête. J'ai un problème similaire, je ne pouvais pas trouver une solution simple, je propose donc cette approche d'utiliser une combinaison de npm et gulp.

Dites que votre fichier gulp est:

var args = require('yargs');

function transform-move-jsx() 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(args.outputDirectory));
};

Et votre fichier npm:

{
  ...
  "scripts": {
    "dev" : "gulp transform-moove-jsx --./output/development/ && gulp one && gulp two",
    "prod" : "gulp transform-moove-jsx --./output/production/  && gulp one && gulp two",
  }
}

Cette approche nécessite que vous utilisiez déjà npm dans vos paramètres, dépend du système et fonctionne moins efficacement avec les effets secondaires éventuels, car chaque tâche npm exécute le fichier gulp plusieurs fois. Mais je le considère plus propre, plus logique et supprime un tas de limitations de gulp.

0
Xun Yang

Pour commencer, pour mémoire, le numéro de github correspondant gulp # 1225 .

Gulp ne peut pas gérer les paramètres dans les tâches. Afin de gérer la construction dev/production, nous pouvons utiliser yargs et gulp-if :

var gulp = require('gulp');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');
var production = argv.production;

Ensuite, par exemple, dans une tâche CSS:

return gulp.src(paths.css)
  .pipe(gulpif(!production, sourcemaps.init()))
  .on('error', handleError('CSS'))
  .pipe(concat('style.min.css'))
  .pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
  .pipe(gulpif(production, minifyCSS()))
  .pipe(sourcemaps.write())
  .pipe(gulp.dest(paths.build + 'css/'));

Comme vous pouvez le constater, l’utilisation de gulp-if gère correctement le tuyau.

Mais ce qui précède doit encore exécuter gulp avec gulp mytask --production et ne convient pas vraiment si la même tâche doit être exécutée plusieurs fois dans une même construction. Ce n'est pas approprié car ce n'est pas du tout DRY.

Par exemple, si vous devez générer plusieurs versions CSS pour différentes parties du site, vous devrez répéter la tâche ci-dessus n fois. Mais comme gulp ne peut pas gérer les paramètres, nous devons faire quelque chose comme:

var taskMethods = {
  css: function (paths) {
    return gulp.src(paths.css)
      .pipe(gulpif(!production, sourcemaps.init()))
      .on('error', handleError('CSS'))
      .pipe(concat('style.min.css'))
      .pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
      .pipe(gulpif(production, minifyCSS()))
      .pipe(sourcemaps.write())
      .pipe(gulp.dest(paths.build + 'css/'));
  }
};

var pathsIndex = {
  css: [...],
  build: '...'
};

var tasksIndex = {
  css: function() { return taskMethods(pathsIndex); }
}

var pathsAdmin = {...};
var tasksAdmin = {...};

gulp.task('cssIndex', tasksIndex.css);
gulp.task('cssAdmin', tasksAdmin.css);

Donc, essentiellement, nous séparons la méthode de tâche de la tâche gulp, avec le coût de devoir spécifier un «câblage» de la méthode de tâche à une nouvelle fonction qui utilise une certaine configuration de chemin. Mais cela présente l'avantage que chaque fois que vous devez modifier une méthode de tâche, elle se trouve au même endroit. Aussi, vous pouvez facilement voir quelle partie du site utilise quelles méthodes.

C’est également ainsi que je traite ce problème dans mon projet gulpfile .

0
Wtower