Ist es möglich, Gulp ein Flag zu übergeben, damit es Aufgaben auf unterschiedliche Weise ausführt?

369

Normalerweise sehen Aufgaben in Gulp folgendermaßen aus:

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

Ist es möglich, ein Befehlszeilenflag an gulp zu übergeben (das ist keine Aufgabe) und Aufgaben basierend darauf ausführen zu lassen? Zum Beispiel

$ gulp my-task -a 1

Und dann in meiner 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));
});
Asolberg
quelle
11
Da es im Knoten ausgeführt wird, können Sie wahrscheinlich process.argvauf die Befehlszeilenargumente zugreifen.
zzzzBov

Antworten:

528

Gulp bietet dafür keine Verwendung an, aber Sie können einen der vielen Parser für Befehlsargumente verwenden. Ich mag yargs. Sollte sein:

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

Sie können es auch kombinieren, gulp-ifum den Stream bedingt weiterzuleiten. Dies ist sehr nützlich für die Erstellung von Entwicklern und Produkten:

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

Und mit gulp my-js-taskoder anrufen gulp my-js-task --production.

Caio Cunha
quelle
45
Dies sollte irgendwie erwähnt werden @ der offizielle Schluck Github, wesentliche Sachen!
Max
2
Dieses Video erklärt, wie dies ohne Yargs erreicht werden kann: youtube.com/watch?v=gRzCAyNrPV8
plankguy
9
Hallo @plankguy, das Video ist sehr schön. Vielen Dank. Es zeigt, wie die Umgebungsvariablen ohne lib von Hand analysiert werden. Ein kleiner Unterschied besteht darin, dass es in dem Video um Umgebungsvariablen geht , während es im obigen Beispiel um Befehlszeilenargumente geht , wobei Yargs ein weiteres Tool ist, das den Verbrauch vereinfacht, indem es das Parsen von Variablen abstrahiert.
Caio Cunha
12
Wenn Sie npm run gulpdann verwenden, sollten Sie es wie verwenden npm run gulp -- --production.
ivkremer
3
Dies wird im offiziellen Schluck Github (wörtlich) erwähnt.
Fracz
101

Bearbeiten

gulp-utilist veraltet und sollte vermieden werden, daher wird empfohlen, stattdessen Minimist zu verwendengulp-util bereits verwendeten verwenden.

Also habe ich einige Zeilen in meiner Gulpfile geändert, um sie zu entfernen gulp-util:

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

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

Original

In meinem Projekt verwende ich das folgende Flag:

gulp styles --theme literature

Gulp bietet dafür ein Objekt gulp.envan. Es ist in neueren Versionen veraltet, daher müssen Sie dafür gulp-util verwenden. Die Aufgaben sehen folgendermaßen aus:

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

Die Umgebungseinstellung ist für alle Unteraufgaben verfügbar. Also kann ich dieses Flag auch für die Überwachungsaufgabe verwenden:

gulp watch --theme literature

Und meine Stilaufgabe funktioniert auch.

Ciao Ralf

RWAM
quelle
6
gulp.envwird veraltet , wie Sie an der Konsolenprotokollmeldung sehen können, wenn Sie es ausführen. Sie bitten Sie, Ihren eigenen Parser zu verwenden und yargsoder vorzuschlagen minimist.
Caio Cunha
2
Vielen Dank an @CaioToOn für Ihren Hinweis. Ich habe meine Antwort und mein Projekt auch aktualisiert;)
RWAM
4
Sie können verkürzen util.env.theme ? util.env.theme : 'main'zu util.env.theme || 'main'. Wie auch immer +1.
Renan
9
gulp-utilVerwendet die minimistBibliothek zum Parsen von Befehlszeilenargumenten. Wenn Sie also verwenden gulp-util, benötigen Sie zu diesem Zweck keine zusätzliche Bibliothek. Dokument: github.com/substack/minimist
Rockallite
57

Hier ist ein kurzes Rezept, das ich gefunden habe:

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

Originalreferenz (nicht mehr verfügbar): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

Alternative mit Minimist

Aus der aktualisierten Referenz: 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
AEQ
quelle
2
Dieser Rezeptlink scheint jetzt weg zu sein. Es gibt eine andere, die stattdessen das Minimist-Paket verwendet: pass-arguments-from-cli.md . Das ist sinnvoll, da gulp selbst Minimist verwendet .
Yuvilio
39

Es gibt eine sehr einfache Möglichkeit, on/offFlags zu erstellen, ohne die Argumente zu analysieren. gulpfile.jsist nur eine Datei, die wie jede andere ausgeführt wird. Sie können also Folgendes tun:

var flags = {
  production: false
};

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

Und verwenden Sie so etwas wie gulp-if, um einen Schritt bedingt auszuführen

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

Durch das Ausführen gulp buildwird ein schönes HTML erstellt, während gulp production buildes minimiert wird.

Emil Ivanov
quelle
2
Tolle Idee, spart mit Yargs. Ich habe dies durch eine 'Vorproduktions'-Aufgabe erweitert, die die Vars festlegt, und dann hat' Produktion 'ein Abhängigkeitsarray von [' Build ',' Vorproduktion ']. Auf diese Weise können Sie einfach die Schluckproduktion ausführen.
Keegan 82
Nett! Ich benutze dies, bevor ich den Stream setze, mitgulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
Henry
Ich denke, das ist der Schluck-Weg, um es zu tun
Gztomas
@ Keegan'shairstyle82 ich etwas ähnliches tat, hatte aber nutzen Laufsequenz , um sicherzustellen , waren keine Bedingungen Rennen , wenn die Eigenschaften einstellen flags.
CalMlynarczyk
3
Der Nachteil dieser Methode ist, dass Sie gulpfile.js jedes Mal ändern müssen, wenn Sie Flag-Variablen ändern möchten, anstatt nur Argumente an den Befehl gulp im Terminal zu übergeben.
18.
33

Wenn Sie einige strenge (geordnete!) Argumente haben, können Sie diese einfach durch Überprüfen erhalten process.argv.

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

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

Führ es aus: gulp --env production

... aber ich denke , dass dies tooo streng und nicht kugelsicher! Also habe ich ein bisschen rumgespielt ... und am Ende diese Utility-Funktion erhalten:

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

Es frisst einen Argumentnamen und sucht danach in process.argv. Wenn nichts gefunden wurde, spuckt es aus null. Andernfalls wird zurückgegeben, wenn es sich nicht um das nächste Argument handelt oder wenn das nächste Argument ein Befehl und kein Wert ist (wir unterscheiden uns durch einen Bindestrich) true. (Das liegt daran, dass der Schlüssel existiert, aber es gibt einfach keinen Wert). Wenn alle vorherigen Fälle fehlschlagen, erhalten wir den nächsten Argumentwert.

> 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, genug für jetzt ... Hier ist ein einfaches Beispiel mit 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"));
});

Starte es gulp --env production

yckart
quelle
if (args[0] === '--env' && args[1] === 'production');Dem Argumentnamen sollte ein Bindestrich vorangestellt werden: mindestens in gulp 3.8.11
piotr_cz
@yckart - Sie sollten wahrscheinlich die Anforderung ('..') für getArg in Ihr Codebeispiel einfügen.
18.
7

Ich habe ein Plugin erstellt, um Parameter über die Befehlszeile in den Task-Rückruf einzufügen.

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

// gulp mytask --production

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

Wenn jemand einen Fehler findet oder eine Verbesserung hat, bin ich glücklich, PRs zusammenzuführen.

stoeffel
quelle
4

Und wenn Sie Typoskript ( gulpfile.ts) verwenden, tun Sie dies für yargs(basierend auf @Caio Cunhas hervorragender Antwort https://stackoverflow.com/a/23038290/1019307 und anderen obigen Kommentaren):

Installieren

npm install --save-dev yargs

typings install dt~yargs --global --save

.ts Dateien

Fügen Sie dies zu den .ts-Dateien hinzu:

import { argv } from 'yargs';

...

  let debug: boolean = argv.debug;

Dies muss in jeder .ts-Datei einzeln erfolgen (auch in den tools/tasks/projectDateien, die in die importiert werden gulpfile.ts/js).

Lauf

gulp build.dev --debug

Oder unter npmdem Arg durch schlucken:

npm run build.dev -- --debug
HankCa
quelle
2

Übergeben Sie Argumente über die Befehlszeile

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

Dann laufen Sie schlucken mit:

$ gulp scripts --env development

Quelle

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

CLI gulp productionruft meine Produktionsaufgabe auf und setzt ein Flag für alle Bedingungen.

Keegan 82
quelle
1

Wir wollten eine andere Konfigurationsdatei für verschiedene Umgebungen übergeben - eine für Produktion , Entwicklung und Test . Dies ist der Code in der Gulp-Datei:

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

Dies ist der Code in der Datei 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);
    }

Und dann schlucken --env=testing

Sara Inés Calderón
quelle
1

Es ist einige Zeit her, seit diese Frage gestellt wurde, aber vielleicht hilft sie jemandem.

Ich verwende GULP CLI 2.0.1 (global installiert) und GULP 4.0.0 (lokal installiert). So machen Sie es ohne zusätzliches Plugin. Ich denke, der Code ist ziemlich selbsterklärend.

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;

Und laufen Sie von der Konsole aus:

gulp availableTasks

Dann laufen Sie und sehen Sie die Unterschiede:

gulp availableTasks --verbose
TMMC
quelle