È possibile passare una bandiera a Gulp per far eseguire le attività in diversi modi?


369

Normalmente nelle attività di Gulp si presenta così:

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

È possibile passare un flag della riga di comando a gulp (che non è un'attività) e far eseguire le attività in modo condizionale in base a quello? Per esempio

$ gulp my-task -a 1

E poi nel mio 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
Poiché è in esecuzione nel nodo, è possibile utilizzare probabilmente process.argvper accedere agli argomenti della riga di comando.
zzzzBov,

Risposte:


528

Gulp non offre alcun tipo di utilità per questo, ma puoi usare uno dei molti parser di comando args. Mi piace yargs. Dovrebbe essere:

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

Puoi anche combinarlo con il gulp-ifpipe condizionale dello stream, molto utile per lo sviluppo dev vs. 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/'));
});

E chiama con gulp my-js-tasko gulp my-js-task --production.


45
Questo dovrebbe essere in qualche modo menzionato @ gulp github ufficiale, roba essenziale!
Max

2
Questo, video spiega come raggiungere questo obiettivo senza yarg: youtube.com/watch?v=gRzCAyNrPV8
plankguy,

9
Ciao @plankguy, il video è molto bello. Grazie. Mostra come analizzare manualmente le variabili di ambiente, senza alcuna lib. Una piccola differenza è che il video riguarda le variabili di ambiente , mentre l'esempio sopra riguarda gli argomenti della riga di comando , in cui Yargs è un altro strumento che aiuta a semplificare il consumo astrattando l'analisi delle variabili.
Caio Cunha,

12
Se lo usi npm run gulp, dovresti usarlo come npm run gulp -- --production.
Ivkremer,

3
Questo è menzionato @ the gulp github ufficiale (letteralmente).
fracz,

101

modificare

gulp-utilè deprecato e dovrebbe essere evitato, quindi si consiglia di utilizzare invece minimista , che gulp-utilgià utilizzato.

Quindi ho rimosso alcune righe nel mio file di dati da rimuovere gulp-util :

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

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

Originale

Nel mio progetto uso il seguente flag:

gulp styles --theme literature

Gulp offre un oggetto gulp.env per questo. È obsoleto nelle versioni più recenti, quindi è necessario utilizzare gulp-util per questo. I compiti si presentano così:

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

L'impostazione dell'ambiente è disponibile durante tutte le attività secondarie. Quindi posso usare questo flag anche sull'attività dell'orologio:

gulp watch --theme literature

E anche il mio compito di stili funziona.

Ciao Ralf


6
gulp.envè obsoleto , come puoi vedere dal messaggio di registro della console durante l'esecuzione. Ti chiedono di usare il tuo parser e suggerire yargso minimist.
Caio Cunha,

2
Grazie @CaioToOn per il tuo suggerimento. Ho aggiornato la mia risposta e anche il mio progetto;)
RWAM

4
È possibile ridurre util.env.theme ? util.env.theme : 'main'a util.env.theme || 'main'. Comunque +1.
Renan,

9
gulp-utilutilizza la minimistlibreria per l'analisi degli argomenti della riga di comando. Quindi, se stai usando gulp-util, non hai bisogno di una libreria aggiuntiva a tale scopo. Documento: github.com/substack/minimist
Rockallite,

57

Ecco una ricetta veloce che ho trovato:

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

Rif. Originale (non più disponibile): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

Alternativa con minimista

Da Rif aggiornato: 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
Quel link ricetta sembra sparito ora. C'è un altro che utilizza invece il pacchetto minimist : pass-arguments-from-cli.md . Questo ha senso dal momento che gulp stesso usa il minimalista .
yuvilio,

39

C'è un modo molto semplice per creare on/offflag senza analizzare gli argomenti. gulpfile.jsè solo un file che viene eseguito come un altro, quindi puoi fare:

var flags = {
  production: false
};

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

E usa qualcosa di simile gulp-ifper eseguire condizionalmente un passaggio

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

L'esecuzione gulp buildprodurrà un bel HTML, mentre gulp production buildlo minimizzerà.


2
Ottima idea, salva usando gli yarg, l'ho esteso avendo un compito di "pre-produzione" che imposta i parametri e quindi "produzione" ha un array di dipendenze di ["build", "pre-produzione"]. In questo modo puoi semplicemente eseguire 'gulp production'.
Keegan 82

Bello! Lo sto usando prima di impostare lo stream, congulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
henry il

Penso che questo sia il modo gulp per farlo
gztomas,

@ Keegan'shairstyle82 Ho fatto qualcosa di simile ma ho dovuto utilizzare la sequenza di corsa per assicurarmi che non ci fossero condizioni di gara durante l'impostazione delle proprietà di flags.
CalMlynarczyk,

3
Lo svantaggio di questo metodo è che devi cambiare gulpfile.js ogni volta che vuoi cambiare le variabili flag, piuttosto che passare semplicemente argomenti al comando gulp nel terminale.
jbyrd,

33

Se hai degli argomenti severi (ordinati!), Puoi ottenerli semplicemente controllando process.argv.

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

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

Eseguilo: gulp --env production

... tuttavia, penso che questo sia troppo rigido e non antiproiettile! Quindi, ho armeggiato un po 'in giro ... e ho finito con questa funzione di utilità:

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

Mangia un nome argomento e lo cercherà in process.argv. Se non è stato trovato nulla, sputa null. Altrimenti se il loro non è un argomento successivo o l'argomento successivo è un comando e non trueviene restituito un valore (differiamo con un trattino) . (Questo perché la chiave esiste, ma non c'è proprio alcun valore). Se tutti i casi precedenti falliranno, il prossimo argomento-valore è ciò che otteniamo.

> 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, abbastanza per ora ... Ecco un semplice esempio usando gulp :

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

Eseguirlo gulp --env production


il nome dell'argomento deve essere preceduto da trattini if (args[0] === '--env' && args[1] === 'production');:, almeno in gulp 3.8.11
piotr_cz,

@yckart - probabilmente dovresti aggiungere il requisito ('..') per getArg nel tuo esempio di codice.
jbyrd,

7

Ho creato un plug-in per iniettare i parametri dalla riga di comando nel callback dell'attività.

gulp.task('mytask', function (production) {
  console.log(production); // => true
});

// gulp mytask --production

https://github.com/stoeffel/gulp-param

Se qualcuno trova un bug o ha un miglioramento, sono felice di unire i PR.


4

E se stai usando typescript ( gulpfile.ts), fallo per yargs(basandosi sull'eccellente risposta di @Caio Cunha https://stackoverflow.com/a/23038290/1019307 e altri commenti sopra):

Installare

npm install --save-dev yargs

typings install dt~yargs --global --save

.ts File

Aggiungi questo ai file .ts:

import { argv } from 'yargs';

...

  let debug: boolean = argv.debug;

Questo deve essere fatto in ogni file .ts singolarmente (anche i tools/tasks/projectfile che vengono importati ingulpfile.ts/js ).

Correre

gulp build.dev --debug

O sotto npmpassare l'arg attraverso per deglutire:

npm run build.dev -- --debug

2

Passa gli argomenti dalla riga di comando

// 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 in production
    .pipe(gulp.dest('dist'));
});

Quindi esegui gulp con:

$ gulp scripts --env development

fonte


2
var isProduction = (process.argv.indexOf("production")>-1);

CLI gulp productionchiama la mia attività di produzione e imposta un flag per tutti i condizionali.


1

Volevamo passare un file di configurazione differente per ambienti diversi - uno per la produzione , dev e test . Questo è il codice nel file gulp:

//passing in flag to gulp to set environment
//var env = gutil.env.env;

if (typeof gutil.env.env === 'string') {
  process.env.NODE_ENV = gutil.env.env;
}

Questo è il codice nel file app.js:

  if(env === 'testing'){
      var Config = require('./config.testing.js');
      var Api = require('./api/testing.js')(Config.web);
    }
    else if(env === 'dev'){
       Config = require('./config.dev.js');
        Api = require('./api/dev.js').Api;
    }
    else{
       Config = require('./config.production.js');
       Api = require('./api/production.js')(Config.web);
    }

E poi eseguirlo sorso --env=testing


1

È passato del tempo da quando questa domanda è stata pubblicata, ma forse aiuterà qualcuno.

Sto usando GULP CLI 2.0.1 (installato a livello globale) e GULP 4.0.0 (installato localmente) ecco come lo fai senza alcun plug-in aggiuntivo. Penso che il codice sia abbastanza esplicativo.

var cp = require('child_process'), 
{ src, dest, series, parallel, watch } = require('gulp');

// == availableTasks: log available tasks to console
function availableTasks(done) {
  var command = 'gulp --tasks-simple';
  if (process.argv.indexOf('--verbose') > -1) {
    command = 'gulp --tasks';
  }
  cp.exec(command, function(err, stdout, stderr) {
    done(console.log('Available tasks are:\n' + stdout));
  });
}
availableTasks.displayName = 'tasks';
availableTasks.description = 'Log available tasks to console as plain text list.';
availableTasks.flags = {
  '--verbose': 'Display tasks dependency tree instead of plain text list.'
};
exports.availableTasks = availableTasks;

Ed esegui dalla console:

gulp availableTasks

Quindi esegui e vedi le differenze:

gulp availableTasks --verbose
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.