Czy można przekazać flagę Gulpowi, aby uruchamiał zadania na różne sposoby?

369

Zwykle w Gulp zadania wyglądają tak:

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

Czy można przekazać flagę wiersza poleceń do przełykania (to nie jest zadanie) i pozwolić, aby uruchamiała zadania warunkowo na tej podstawie? Na przykład

$ gulp my-task -a 1

A potem w moim 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
źródło
11
Ponieważ jest uruchomiony w węźle, prawdopodobnie możesz użyć go, process.argvaby uzyskać dostęp do argumentów wiersza poleceń.
zzzzBov

Odpowiedzi:

528

Gulp nie oferuje do tego żadnego zastosowania, ale możesz użyć jednego z wielu parserów argumentów poleceń. Lubię yargs. Powinien być:

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

Możesz go również połączyć z gulp-ifwarunkowym potokiem strumienia, co jest bardzo przydatne w tworzeniu i tworzeniu aplikacji:

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

I zadzwoń za pomocą gulp my-js-tasklub gulp my-js-task --production.

Caio Cunha
źródło
45
To powinno być jakoś wspomniane @ oficjalny github gulp, niezbędne rzeczy!
Max.
2
To wideo wyjaśnia, jak to osiągnąć bez yargs: youtube.com/watch?v=gRzCAyNrPV8
plankguy
9
Cześć @plankguy, wideo jest bardzo miłe. Dzięki. Pokazuje, jak ręcznie parsować zmienne środowiskowe, bez żadnej biblioteki lib. Niewielka różnica polega na tym, że wideo dotyczy zmiennych środowiskowych , podczas gdy powyższy przykład dotyczy argumentów wiersza poleceń , gdzie Yargs jest kolejnym narzędziem, które pomaga uprościć zużycie poprzez abstrakcję analizy zmiennych.
Caio Cunha
12
Jeśli używasz npm run gulp, powinieneś używać go jak npm run gulp -- --production.
ivkremer,
3
Jest to wspomniane @ oficjalny github gulub (dosłownie).
fracz
101

Edytować

gulp-utiljest przestarzałe i należy go unikać, dlatego zaleca się stosowanie zamiast tego minimalistycznego , który gulp-utiljuż był używany.

Więc zmieniłem niektóre linie w moim pliku gulp, aby usunąć gulp-util:

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

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

Oryginalny

W moim projekcie używam następującej flagi:

gulp styles --theme literature

Gulp oferuje do tego obiekt gulp.env. Jest to przestarzałe w nowszych wersjach, więc musisz do tego użyć gulp-util. Zadania wyglądają następująco:

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

Ustawienie środowiska jest dostępne podczas wszystkich podzadań. Więc mogę użyć tej flagi również w zadaniu obserwacyjnym:

gulp watch --theme literature

I moje zadanie stylów też działa.

Ciao Ralf

RWAM
źródło
6
gulp.envjest przestarzałe , co widać po komunikacie dziennika konsoli podczas jego uruchamiania. Proszą o użycie własnego parsera i sugerują yargslub minimist.
Caio Cunha,
2
Dzięki @CaioToOn za podpowiedź. Zaktualizowałem swoją odpowiedź i mój projekt;)
RWAM
4
Możesz skrócić util.env.theme ? util.env.theme : 'main'do util.env.theme || 'main'. W każdym razie +1.
Renan
9
gulp-utilwykorzystuje minimistbibliotekę do analizy argumentów wiersza poleceń. Więc jeśli używasz gulp-util, nie potrzebujesz dodatkowej biblioteki do tego celu. Dokument: github.com/substack/minimist
Rockallite
57

Oto szybki przepis, który znalazłem:

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

Oryginalny numer referencyjny (już niedostępny): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

Alternatywa z minimalistą

Zaktualizowany Ref: 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
źródło
2
Link do przepisu wydaje się teraz zniknąć. Istnieje inny, który zamiast tego używa pakietu minimalistycznego : pass-arguments-from-cli.md . Ma to sens, ponieważ sam łyk używa minimalisty .
yuvilio
39

Istnieje bardzo prosty sposób na tworzenie on/offflag bez analizowania argumentów. gulpfile.jsto tylko plik, który jest wykonywany jak każdy inny, więc możesz:

var flags = {
  production: false
};

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

I użyj czegoś takiego, gulp-ifaby warunkowo wykonać krok

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

Wykonanie gulp buildwygeneruje niezły html, a jednocześnie gulp production buildgo zminimalizuje.

Emil Iwanow
źródło
2
Świetny pomysł, oszczędza przy użyciu yargs, rozszerzyłem to o zadanie „przedprodukcyjne”, które ustawia zmienne, a następnie „produkcja” ma tablicę zależności [„kompilacja”, „przedprodukcja”]. W ten sposób możesz po prostu uruchomić „produkcję łyków”.
Keegan 82
Miły! Używam tego przed ustawieniem strumienia, zgulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
henry,
Myślę, że to jest
szybki
@ Keegan'shairstyle82 Zrobiłem coś podobnego, ale musiałem użyć sekwencji biegu, aby upewnić się, że nie ma warunków wyścigu podczas ustawiania właściwości flags.
CalMlynarczyk,
3
Wadą tej metody jest to, że musisz zmieniać gulpfile.js za każdym razem, gdy chcesz zmienić zmienne flag, zamiast tylko przekazywać argumenty do komendy gulp w terminalu.
jbyrd
33

Jeśli masz jakieś ścisłe (uporządkowane!) Argumenty, możesz je po prostu sprawdzić process.argv.

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

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

Wykonaj to: gulp --env production

... Jednak myślę, że to jest za dlugich surowe i nie kuloodporne! Więc trochę się bawiłem ... i skończyłem z tą funkcją narzędzia:

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

Zjada nazwę argumentu i wyszuka to w process.argv. Jeśli nic nie znaleziono, wypluwa się null. W przeciwnym razie, jeśli nie jest to kolejny argument lub następny argument jest poleceniem, a nie wartością (różni się myślnikiem), truezostanie zwrócony. (Jest tak, ponieważ klucz istnieje, ale po prostu nie ma wartości). Jeśli wszystkie poprzednie przypadki zakończą się niepowodzeniem, otrzymamy następny argument-wartość.

> 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, na razie wystarczy ... Oto prosty przykład użycia 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"));
});

Uruchom gulp --env production

yckart
źródło
nazwa argumentu powinna być poprzedzona myślnikiem ( if (args[0] === '--env' && args[1] === 'production');
-ami):,
@yckart - w twoim kodzie prawdopodobnie powinieneś dodać wymaganie ('..') dla getArg.
jbyrd
7

Zbudowałem wtyczkę do wstrzykiwania parametrów z wiersza polecenia do wywołania zwrotnego zadania.

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

// gulp mytask --production

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

Jeśli ktoś znajdzie błąd lub poprawi go, z przyjemnością scalę PR.

stoeffel
źródło
4

A jeśli używasz maszynopisu (gulpfile.ts ), zrób to yargs(w oparciu o doskonałą odpowiedź @Caio Cunha https://stackoverflow.com/a/23038290/1019307 i inne komentarze powyżej):

zainstalować

npm install --save-dev yargs

typings install dt~yargs --global --save

.ts akta

Dodaj to do plików .ts:

import { argv } from 'yargs';

...

  let debug: boolean = argv.debug;

Należy to zrobić w każdym pliku .ts osobno (nawet w pliku tools/tasks/project pliki importowane do gulpfile.ts/js).

Biegać

gulp build.dev --debug

Lub pod npmprzekazać arg, aby przełknąć:

npm run build.dev -- --debug
HankCa
źródło
2

Przekaż argumenty z wiersza poleceń

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

Następnie uruchom łyk za pomocą:

$ gulp scripts --env development

Źródło

HaNdTriX
źródło
2
var isProduction = (process.argv.indexOf("production")>-1);

Interfejs CLI gulp productionwywołuje moje zadanie produkcyjne i ustawia flagę dla wszystkich warunków warunkowych.

Keegan 82
źródło
1

Chcieliśmy przekazać inny plik konfiguracyjny dla różnych środowisk - jeden dla produkcji , dev i testowania . To jest kod w pliku 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;
}

To jest kod w pliku 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);
    }

A potem przełknąć --env=testing

Sara Inés Calderón
źródło
1

Minęło trochę czasu, odkąd to pytanie zostało opublikowane, ale może komuś pomoże.

Korzystam z GULP CLI 2.0.1 (instalowany globalnie), a GULP 4.0.0 (instalowany lokalnie) oto jak to zrobić bez dodatkowej wtyczki. Myślę, że kod jest dość zrozumiały.

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;

I uruchom z konsoli:

gulp availableTasks

Następnie uruchom i zobacz różnice:

gulp availableTasks --verbose
TMMC
źródło