È 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.