374 votes

Est-il possible de passer un drapeau à Gulp pour qu'il exécute les tâches de différentes manières ?

Normalement, dans Gulp, les tâches ressemblent à ceci :

gulp.task('my-task', function() {
    return gulp.src(options.SCSS_SOURCE)
        .pipe(sass({style:'nested'}))
        .pipe(autoprefixer('last 10 version'))
        .pipe(concat('style.css'))
        .pipe(gulp.dest(options.SCSS_DEST));
});

Est-il possible de passer un drapeau de ligne de commande à gulp (qui n'est pas une tâche) et de faire en sorte qu'il exécute des tâches de manière conditionnelle en fonction de cela ? Par exemple

$ gulp my-task -a 1

Et ensuite dans mon gulpfile.js :

gulp.task('my-task', function() {
        if (a == 1) {
            var source = options.SCSS_SOURCE;
        } else {
            var source = options.OTHER_SOURCE;
        }
        return gulp.src(source)
            .pipe(sass({style:'nested'}))
            .pipe(autoprefixer('last 10 version'))
            .pipe(concat('style.css'))
            .pipe(gulp.dest(options.SCSS_DEST));
});

11 votes

Comme il s'exécute en node, vous pourriez probablement utiliser process.argv pour accéder aux arguments de la ligne de commande.

529voto

CaioToOn Points 9069

Gulp ne propose pas d'utilitaire pour cela, mais vous pouvez utiliser l'un des nombreux analyseurs d'arguments de commande. J'aime yargs . Devrait être :

var argv = require('yargs').argv;

gulp.task('my-task', function() {
    return gulp.src(argv.a == 1 ? options.SCSS_SOURCE : options.OTHER_SOURCE)
        .pipe(sass({style:'nested'}))
        .pipe(autoprefixer('last 10 version'))
        .pipe(concat('style.css'))
        .pipe(gulp.dest(options.SCSS_DEST));
});

Vous pouvez également le combiner avec gulp-if pour canaliser le flux de manière conditionnelle, très utile pour les constructions de type "dev" ou "prod" :

var argv = require('yargs').argv,
    gulpif = require('gulp-if'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify');

gulp.task('my-js-task', function() {
  gulp.src('src/**/*.js')
    .pipe(concat('out.js'))
    .pipe(gulpif(argv.production, uglify()))
    .pipe(gulpif(argv.production, rename({suffix: '.min'})))
    .pipe(gulp.dest('dist/'));
});

Et appelez avec gulp my-js-task o gulp my-js-task --production .

45 votes

Cela devrait être mentionné d'une manière ou d'une autre sur le github officiel de gulp, c'est essentiel !

2 votes

Cette vidéo explique comment y parvenir sans yargs : youtube.com/watch?v=gRzCAyNrPV8

9 votes

Salut @plankguy, la vidéo est très belle. Merci. Elle montre comment analyser les variables d'environnement à la main, sans aucune librairie. Une petite différence est que la vidéo parle de variables d'environnement alors que l'exemple ci-dessus concerne arguments de ligne de commande Yargs est un autre outil qui permet de simplifier la consommation en abstrayant l'analyse des variables.

103voto

Rwam Dev Points 840

Modifier

gulp-util es déprécié et devrait être évité, il est donc recommandé d'utiliser minimaliste à la place, ce qui gulp-util déjà utilisé.

J'ai donc changé quelques lignes dans mon gulpfile pour enlever gulp-util :

var argv = require('minimist')(process.argv.slice(2));

gulp.task('styles', function() {
  return gulp.src(['src/styles/' + (argv.theme || 'main') + '.scss'])
    …
});

Original

Dans mon projet, j'utilise le drapeau suivant :

gulp styles --theme literature

Gulp propose un objet gulp.env pour ça. Il est déprécié dans les versions plus récentes, vous devez donc utiliser gulp-util pour cela. Les tâches ressemblent à ceci :

var util = require('gulp-util');

gulp.task('styles', function() {
  return gulp.src(['src/styles/' + (util.env.theme ? util.env.theme : 'main') + '.scss'])
    .pipe(compass({
        config_file: './config.rb',
        sass   : 'src/styles',
        css    : 'dist/styles',
        style  : 'expanded'

    }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'ff 17', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(livereload(server))
    .pipe(gulp.dest('dist/styles'))
    .pipe(notify({ message: 'Styles task complete' }));
});

Le paramètre d'environnement est disponible pendant toutes les sous-tâches. Je peux donc utiliser cet indicateur sur la tâche de surveillance également :

gulp watch --theme literature

Et ma tâche de style fonctionne également.

Ciao Ralf

6 votes

gulp.env est déprécié comme vous pouvez le voir dans le message de la console lorsque vous l'exécutez. Ils vous demandent d'utiliser votre propre parser et suggèrent yargs o minimist .

2 votes

Merci @CaioToOn pour votre conseil. J'ai mis à jour ma réponse et mon projet aussi ;)

4 votes

Vous pouvez raccourcir util.env.theme ? util.env.theme : 'main' a util.env.theme || 'main' . En tout cas +1.

58voto

AEQ Points 103

Voici une recette rapide que j'ai trouvée :

gulpfile.js

var gulp   = require('gulp');

// npm install gulp yargs gulp-if gulp-uglify
var args   = require('yargs').argv;
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');

var isProduction = args.env === 'production';

gulp.task('scripts', function() {
  return gulp.src('**/*.js')
    .pipe(gulpif(isProduction, uglify())) // only minify if production
    .pipe(gulp.dest('dist'));
});

CLI

gulp scripts --env production

Réf. originale (n'est plus disponible) : https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

Alternative avec minimaliste

De la réf. actualisée https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli.md

gulpfile.js

// npm install --save-dev gulp gulp-if gulp-uglify minimist

var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');

var minimist = require('minimist');

var knownOptions = {
  string: 'env',
  default: { env: process.env.NODE_ENV || 'production' }
};

var options = minimist(process.argv.slice(2), knownOptions);

gulp.task('scripts', function() {
  return gulp.src('**/*.js')
    .pipe(gulpif(options.env === 'production', uglify())) // only minify if production
    .pipe(gulp.dest('dist'));
});

CLI

gulp scripts --env production

2 votes

Le lien vers cette recette semble avoir disparu. Il y en a une autre qui utilise le paquet minimist à la place : pass-arguments-from-cli.md . C'est logique puisque gulp lui-même utilise minimaliste .

39voto

Emil Ivanov Points 18594

Il y a un moyen très simple de faire on/off sans analyser les arguments. gulpfile.js est juste un fichier qui est exécuté comme n'importe quel autre, donc vous pouvez faire :

var flags = {
  production: false
};

gulp.task('production', function () {
  flags.production = true;
});

Et utiliser quelque chose comme gulp-if pour exécuter conditionnellement une étape

gulp.task('build', function () {
  gulp.src('*.html')
    .pipe(gulp_if(flags.production, minify_html()))
    .pipe(gulp.dest('build/'));
});

Exécuter gulp build produira un joli html, tandis que gulp production build va le minifier.

2 votes

Bonne idée, les sauvegardes utilisant les yargs, j'ai étendu cela en ayant une tâche 'pré-production' qui définit les variables et ensuite 'production' a un tableau de dépendance de ['build', 'pré-production']. De cette façon, vous pouvez simplement lancer 'gulp production'.

0 votes

Joli ! J'utilise ceci avant de mettre en place le flux, avec gulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });

0 votes

Je pense que c'est la façon gulp de le faire.

33voto

yckart Points 7517

Si vous avez des arguments stricts (ordonnés !), vous pouvez les obtenir en vérifiant simplement les éléments suivants process.argv .

var args = process.argv.slice(2);

if (args[0] === "--env" && args[1] === "production");

Exécutez-le : gulp --env production

...cependant, je pense que c'est tooo stricte et pas bulletproof ! J'ai donc bricolé un peu... et j'ai fini par obtenir cette fonction utilitaire :

function getArg(key) {
  var index = process.argv.indexOf(key);
  var next = process.argv[index + 1];
  return (index < 0) ? null : (!next || next[0] === "-") ? true : next;
}

Il mange un nom d'argument et cherchera celui-ci dans process.argv . Si rien n'a été trouvé, il crache null . Sinon, s'il n'y a pas d'argument suivant ou si l'argument suivant est une commande et non une valeur (nous différons avec un tiret) true est renvoyé. (C'est parce que la clé existe, mais qu'il n'y a pas de valeur). Si tous les cas précédents échouent, la prochaine valeur de l'argument est ce que nous obtenons.

> gulp watch --foo --bar 1337 -boom "Foo isn't equal to bar."

getArg("--foo") // => true
getArg("--bar") // => "1337"
getArg("-boom") // => "Foo isn't equal to bar."
getArg("--404") // => null

Ok, ça suffit pour le moment... Voici un exemple simple utilisant gobler :

var gulp = require("gulp");
var sass = require("gulp-sass");
var rename = require("gulp-rename");

var env = getArg("--env");

gulp.task("styles", function () {
  return gulp.src("./index.scss")
  .pipe(sass({
    style: env === "production" ? "compressed" : "nested"
  }))
  .pipe(rename({
    extname: env === "production" ? ".min.css" : ".css"
  }))
  .pipe(gulp.dest("./build"));
});

Exécutez-le gulp --env production

0 votes

Le nom de l'argument doit être précédé d'un tiret(s) : if (args[0] === '--env' && args[1] === 'production'); , du moins dans gulp 3.8.11

0 votes

@yckart - vous devriez probablement ajouter le require(' ') pour getArg dans votre exemple de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X