Apakah mungkin untuk memberikan bendera kepada Gulp agar menjalankan tugas dengan cara yang berbeda?

369

Biasanya dalam tugas Gulp terlihat seperti ini:

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

Apakah mungkin untuk mengirimkan flag baris perintah ke tegukan (itu bukan tugas) dan menjalankannya berdasarkan persyaratan itu? Contohnya

$ gulp my-task -a 1

Dan kemudian di gulpfile.js saya:

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
sumber
11
Karena berjalan dalam node, Anda mungkin dapat menggunakan process.argvuntuk mengakses argumen baris perintah.
zzzzBov

Jawaban:

528

Gulp tidak menawarkan utilitas apa pun untuk itu, tetapi Anda dapat menggunakan salah satu dari banyak parser perintah args. Saya suka yargs. Seharusnya:

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

Anda juga dapat menggabungkannya dengan gulp-ifuntuk mengalirkan aliran secara kondisional, sangat berguna untuk pengembangan 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/'));
});

Dan telepon dengan gulp my-js-taskatau gulp my-js-task --production.

Caio Cunha
sumber
45
Ini entah bagaimana harus disebutkan @ github tegukan resmi, hal-hal penting!
Maks
2
Ini, video menjelaskan cara mencapai ini tanpa yargs: youtube.com/watch?v=gRzCAyNrPV8
plankguy
9
Hai @plankguy, videonya sangat bagus. Terima kasih. Ini menunjukkan cara mem-parsing variabel lingkungan dengan tangan, tanpa lib. Perbedaan kecil adalah bahwa video adalah tentang variabel lingkungan , sedangkan contoh di atas adalah tentang argumen baris perintah , di mana Yargs adalah alat lain yang membantu menyederhanakan konsumsi dengan mengabstraksi variabel parsing.
Caio Cunha
12
Jika Anda menggunakan npm run gulpmaka Anda harus menggunakannya seperti npm run gulp -- --production.
ivkremer
3
Ini disebutkan @ gulp github resmi (secara harfiah).
fracz
101

Edit

gulp-utilsudah usang dan harus dihindari, oleh karena itu disarankan untuk menggunakan minimalis , yang gulp-utilsudah digunakan.

Jadi saya telah mengubah beberapa baris di gulpfile saya untuk menghapus gulp-util:

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

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

Asli

Dalam proyek saya, saya menggunakan bendera berikut:

gulp styles --theme literature

Gulp menawarkan objek gulp.envuntuk itu. Ini sudah usang dalam versi yang lebih baru, jadi Anda harus menggunakan gulp-util untuk itu. Tugasnya terlihat seperti ini:

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

Pengaturan lingkungan tersedia selama semua subtugas. Jadi saya bisa menggunakan bendera ini pada tugas jaga juga:

gulp watch --theme literature

Dan tugas gaya saya juga berhasil.

Ciao Ralf

RWAM
sumber
6
gulp.envsedang tidak digunakan lagi , seperti yang Anda lihat pada pesan log konsol saat menjalankannya. Mereka meminta Anda untuk menggunakan parser Anda sendiri dan menyarankan yargsatau minimist.
Caio Cunha
2
Terima kasih @CoToOn atas petunjuk Anda. Saya telah memperbarui jawaban dan proyek saya juga;)
RWAM
4
Anda dapat mempersingkat util.env.theme ? util.env.theme : 'main'menjadi util.env.theme || 'main'. Pokoknya +1.
Renan
9
gulp-utilmenggunakan minimistperpustakaan untuk parsing argumen baris perintah. Jadi jika Anda menggunakan gulp-util, Anda tidak perlu perpustakaan tambahan untuk tujuan itu. Dokumen: github.com/substack/minimist
Rockallite
57

Inilah resep cepat yang saya temukan:

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

Ref Asli (tidak tersedia lagi): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

Alternatif dengan minimalis

Dari Ref Terkini: 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
sumber
2
Tautan resep itu sepertinya hilang sekarang. Ada satu lagi yang menggunakan paket minimalis sebagai gantinya: pass-arguments-from-cli.md . Itu masuk akal karena tegukan itu sendiri menggunakan minimalis .
yuvilio
39

Ada cara yang sangat sederhana untuk melakukan on/offflag tanpa menguraikan argumen. gulpfile.jshanyalah sebuah file yang dieksekusi seperti yang lain, sehingga Anda dapat melakukannya:

var flags = {
  production: false
};

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

Dan gunakan sesuatu seperti gulp-ifmengeksekusi langkah secara kondisional

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

Eksekusi gulp buildakan menghasilkan html yang bagus, sementara gulp production buildakan memperkecilnya.

Emil Ivanov
sumber
2
Ide bagus, menghemat menggunakan yargs, saya telah memperpanjang ini dengan memiliki tugas 'pra-produksi' yang mengatur vars dan kemudian 'produksi' memiliki array dependensi ['build', 'pra-produksi']. Dengan begitu Anda bisa menjalankan 'tegukan produksi'.
Keegan 82
Bagus! Saya menggunakan ini sebelum mengatur aliran, dengangulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
henry
Saya pikir ini adalah cara menelan untuk melakukannya
gztomas
@ Keegan'shairstyle82 Saya melakukan sesuatu yang serupa tetapi harus menggunakan run-sequence untuk memastikan tidak ada kondisi balapan saat menyetel properti flags.
CalMlynarczyk
3
Kerugian dari metode ini adalah Anda harus mengubah gulpfile.js setiap kali Anda ingin mengubah variabel flag, daripada hanya meneruskan argumen ke perintah gulp di terminal.
jbyrd
33

Jika Anda memiliki beberapa argumen ketat (dipesan!), Maka Anda bisa mendapatkannya hanya dengan memeriksa process.argv.

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

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

Jalankan: gulp --env production

... Namun, saya berpikir bahwa ini adalah tooo ketat dan tidak antipeluru! Jadi, saya mengutak-atik sedikit ... dan berakhir dengan fungsi utilitas ini:

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

Ini makan argumen-nama dan akan mencari di ini process.argv. Jika tidak ada yang ditemukan, ia dimuntahkan null. Kalau tidak, jika tidak ada argumen berikutnya atau argumen berikutnya adalah perintah dan bukan nilai (kami berbeda dengan tanda hubung) trueakan dikembalikan. (Itu karena kuncinya ada, tetapi tidak ada nilai). Jika semua kasus sebelumnya akan gagal, nilai argumen berikutnya adalah apa yang kita dapatkan.

> 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

Oke, cukup untuk sekarang ... Ini contoh sederhana menggunakan tegukan :

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

Menjalankannya gulp --env production

yaart
sumber
nama argumen harus diawali dengan tanda hubung if (args[0] === '--env' && args[1] === 'production');:, setidaknya dalam tegukan 3.8.11
piotr_cz
@yckart - Anda mungkin harus menambahkan persyaratan ('..') untuk getArg dalam contoh kode Anda.
jbyrd
7

Saya membangun sebuah plugin untuk menyuntikkan parameter dari commandline ke dalam callback tugas.

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

// gulp mytask --production

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

Jika seseorang menemukan bug atau mengalami peningkatan, saya senang menggabungkan PR.

stoeffel
sumber
4

Dan jika Anda menggunakan naskah ( gulpfile.ts) maka lakukan ini untuk yargs(membangun jawaban sempurna @Caio Cunha https://stackoverflow.com/a/23038290/1019307 dan komentar lainnya di atas):

Install

npm install --save-dev yargs

typings install dt~yargs --global --save

.ts file

Tambahkan ini ke file .ts:

import { argv } from 'yargs';

...

  let debug: boolean = argv.debug;

Ini harus dilakukan di setiap file .ts secara individual (bahkan tools/tasks/projectfile yang diimpor ke dalam gulpfile.ts/js).

Lari

gulp build.dev --debug

Atau di bawah npmlulus arg hingga menelan:

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

Lewati argumen dari baris perintah

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

Kemudian jalankan tegukan dengan:

$ gulp scripts --env development

Sumber

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

CLI gulp productionmemanggil tugas produksi saya dan menetapkan bendera untuk semua persyaratan.

Keegan 82
sumber
1

Kami ingin memberikan file konfigurasi yang berbeda untuk lingkungan yang berbeda - satu untuk produksi , pengembangan , dan pengujian . Ini adalah kode dalam file tegukan:

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

Ini adalah kode dalam 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);
    }

Dan kemudian untuk menjalankannya tegukan --env=testing

Sara Inés Calderón
sumber
1

Sudah beberapa waktu sejak pertanyaan ini diposting, tetapi mungkin itu akan membantu seseorang.

Saya menggunakan GULP CLI 2.0.1 (diinstal secara global) dan GULP 4.0.0 (diinstal secara lokal) di sini adalah bagaimana Anda melakukannya tanpa plugin tambahan. Saya pikir kode ini cukup jelas.

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;

Dan lari dari konsol:

gulp availableTasks

Kemudian jalankan dan lihat perbedaannya:

gulp availableTasks --verbose
TMMC
sumber