เป็นไปได้ไหมที่จะส่งค่าสถานะไปที่ Gulp เพื่อให้มันทำงานในรูปแบบที่แตกต่างกัน?


369

โดยปกติในภารกิจอึกมีลักษณะเช่นนี้:

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

เป็นไปได้หรือไม่ที่จะส่งการตั้งค่าสถานะบรรทัดคำสั่งไปที่อึก (นั่นไม่ใช่งาน) และให้มันรันงานตามเงื่อนไขนั้น ตัวอย่างเช่น

$ gulp my-task -a 1

และใน 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
ขณะที่มันกำลังทำงานในโหนดคุณอาจใช้process.argvเพื่อเข้าถึงอาร์กิวเมนต์บรรทัดคำสั่ง
zzzzBov

คำตอบ:


528

อึกไม่ได้นำเสนอการใช้ใด ๆ สำหรับสิ่งนั้น แต่คุณสามารถใช้หนึ่งในหลาย ๆ คำสั่ง args parsers yargsผมชอบ ควรจะเป็น:

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

นอกจากนี้คุณยังสามารถรวมเข้ากับgulp-ifเพื่อส่งกระแสข้อมูลแบบมีเงื่อนไขซึ่งมีประโยชน์มากสำหรับการสร้าง dev และผลิตภัณฑ์แยง:

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

และการโทรที่มีหรือgulp my-js-taskgulp my-js-task --production


45
นี่ควรจะกล่าวถึงอย่างใดอย่างหนึ่ง @ git gulp อย่างเป็นทางการสิ่งที่จำเป็น!
Max

2
นี่วิดีโออธิบายวิธีการทำสิ่งนี้ให้สำเร็จโดยไม่มี yargs: youtube.com/watch?v=gRzCAyNrPV8
plankguy

9
สวัสดี @plankguy วิดีโอนี้ดีมาก ขอบคุณ มันแสดงให้เห็นถึงวิธีการแยกวิเคราะห์ตัวแปรสภาพแวดล้อมด้วยมือโดยไม่ต้อง lib ใด ๆ ข้อแตกต่างเล็ก ๆ คือวิดีโอเป็นเรื่องเกี่ยวกับตัวแปรสภาพแวดล้อมในขณะที่ตัวอย่างข้างต้นเกี่ยวกับอาร์กิวเมนต์บรรทัดคำสั่งที่ Yargs เป็นเครื่องมืออื่นที่ช่วยลดความสิ้นเปลืองของการบริโภคโดยการแยกวิเคราะห์ตัวแปร
Caio Cunha

12
ถ้าคุณใช้แล้วคุณควรจะใช้มันเหมือนnpm run gulp npm run gulp -- --production
ivkremer

3
นี่ถูกกล่าวถึง @ gulp gulub อย่างเป็นทางการ (ตามตัวอักษร)
fracz

101

แก้ไข

gulp-utilจะเลิกใช้และควรจะหลีกเลี่ยงดังนั้นจึงขอแนะนำให้ใช้minimistแทนซึ่งgulp-utilใช้อยู่แล้ว

ดังนั้นฉันจึงเปลี่ยนบางบรรทัดใน gulpfile ของฉันเพื่อลบgulp-util:

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

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

เป็นต้นฉบับ

ในโครงการของฉันฉันใช้ธงต่อไปนี้:

gulp styles --theme literature

อึกนำเสนอวัตถุgulp.envสำหรับการที่ มันเลิกใช้แล้วในเวอร์ชันที่ใหม่กว่าดังนั้นคุณต้องใช้ gulp-util งานมีลักษณะดังนี้:

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

การตั้งค่าสภาพแวดล้อมพร้อมใช้งานระหว่างงานย่อยทั้งหมด ดังนั้นฉันสามารถใช้ธงนี้ในภารกิจการดูได้เช่นกัน:

gulp watch --theme literature

และสไตล์งานของฉันก็ใช้งานได้

Ciao Ralf


6
gulp.envกำลังเลิกใช้แล้วตามที่คุณเห็นโดยบันทึกข้อความคอนโซลเมื่อเรียกใช้ พวกเขาขอให้คุณใช้ตัวแยกวิเคราะห์ของคุณเองและแนะนำหรือyargs minimist
Caio Cunha

2
ขอบคุณ @CaioToOn สำหรับคำใบ้ของคุณ ฉันได้อัปเดตคำตอบและโปรเจคของฉันแล้วเช่นกัน)
RWAM

4
คุณสามารถร่นไปutil.env.theme ? util.env.theme : 'main' util.env.theme || 'main'อย่างไรก็ตาม +1
Renan

9
gulp-utilใช้minimistไลบรารีสำหรับการแยกวิเคราะห์บรรทัดคำสั่ง ดังนั้นหากคุณกำลังใช้gulp-utilคุณไม่จำเป็นต้องมีห้องสมุดเพิ่มเติมเพื่อจุดประสงค์นั้น เอกสาร: github.com/substack/minimist
Rockallite

57

นี่คือสูตรสั้น ๆ ที่ฉันพบ:

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

การอ้างอิงดั้งเดิม (ไม่สามารถใช้งานได้อีกต่อไป): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md

ทางเลือกที่มี minimist

จากการอัปเดตที่อ้างอิงแล้ว: 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
ลิงค์สูตรนั้นหายไปแล้ว มีอีกหนึ่งที่ใช้แพคเกจ minimist แทน: pass-arguments-from-cli.md ที่ทำให้รู้สึกตั้งแต่อึกตัวเองใช้ minimist
yuvilio

39

มีวิธีง่าย ๆ ในการทำon/offแฟล็กโดยไม่ต้องแยกวิเคราะห์อาร์กิวเมนต์ gulpfile.jsเป็นเพียงไฟล์ที่ดำเนินการเหมือนอย่างอื่นดังนั้นคุณสามารถทำได้:

var flags = {
  production: false
};

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

และใช้สิ่งที่ต้องการgulp-ifดำเนินการตามขั้นตอนอย่างมีเงื่อนไข

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

การดำเนินการgulp buildจะสร้าง HTML ที่ดีในขณะที่gulp production buildจะลดขนาดให้เล็กลง


2
ความคิดที่ยอดเยี่ยมบันทึกโดยใช้ yargs ฉันได้ขยายงานนี้โดยมีงาน 'pre-production' ที่กำหนด vars และ 'production' มีอาร์เรย์อ้างอิงของ ['build', 'pre-production'] ด้วยวิธีนี้คุณสามารถเรียกใช้ 'การผลิตอึก'
คีแกน 82

ดี! ฉันใช้สิ่งนี้ก่อนตั้งค่าสตรีมด้วยgulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
เฮนรี่

ฉันคิดว่านี่เป็นวิธีที่อึกที่จะทำ
gztomas

@ Keegan'shairstyle82 ผมทำอะไรที่คล้ายกัน แต่ต้องใช้ระยะลำดับflagsเพื่อให้แน่ใจว่าไม่มีเงื่อนไขการแข่งขันเมื่อตั้งค่าคุณสมบัติของ
CalMlynarczyk

3
ข้อเสียของวิธีนี้คือคุณต้องเปลี่ยน gulpfile.js ทุกครั้งที่คุณต้องการเปลี่ยนตัวแปรแฟล็กแทนที่จะส่งผ่านอาร์กิวเมนต์ไปยังคำสั่ง gulp ในเทอร์มินัล
jbyrd

33

หากคุณได้เข้มงวด (สั่ง!) process.argvข้อโต้แย้งบางส่วนแล้วคุณสามารถรับได้โดยเพียงแค่การตรวจสอบ

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

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

ดำเนินการ: gulp --env production

... แต่ผมคิดว่านี่เป็นtoooเข้มงวดและไม่กันกระสุน! ดังนั้นฉันเล่นนิด ๆ หน่อย ๆ รอบ ... และจบลงด้วยฟังก์ชั่นยูทิลิตี้นี้:

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

process.argvมันกินอาร์กิวเมนต์ชื่อและจะค้นหาในครั้งนี้ nullถ้าไม่มีอะไรก็พบว่ามันคายออกมา มิฉะนั้นถ้าไม่ใช่อาร์กิวเมนต์ถัดไปหรืออาร์กิวเมนต์ถัดไปคือคำสั่งและไม่ใช่ค่า (เราแตกต่างกับเส้นประ) trueจะได้รับคืน (นั่นเป็นเพราะกุญแจมีอยู่ แต่ไม่มีค่า) หากทุกกรณีก่อนหน้านี้จะล้มเหลวอาร์กิวเมนต์ค่าถัดไปคือสิ่งที่เราได้รับ

> 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

ตกลงเพียงพอแล้วตอนนี้ ... นี่เป็นตัวอย่างง่ายๆที่ใช้อึก :

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

เรียกใช้ gulp --env production


ชื่ออาร์กิวเมนต์ควรขึ้นต้นด้วย dash (es): if (args[0] === '--env' && args[1] === 'production');อย่างน้อยในอึก 3.8.11
piotr_cz

@yckart - คุณควรเพิ่มความต้องการ ('.. ') สำหรับ getArg ในตัวอย่างโค้ดของคุณ
jbyrd

7

ฉันสร้างปลั๊กอินเพื่อฉีดพารามิเตอร์จาก commandline ไปที่ callback งาน

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

// gulp mytask --production

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

หากมีคนพบข้อบกพร่องหรือมีการปรับปรุงฉันมีความสุขที่จะรวม PRs


4

และหากคุณใช้ typescript ( gulpfile.ts) ให้ทำเช่นนี้เพื่อyargsสร้างคำตอบที่ยอดเยี่ยมของ @Caio Cunha https://stackoverflow.com/a/23038290/1019307และความคิดเห็นอื่น ๆ ด้านบน):

ติดตั้ง

npm install --save-dev yargs

typings install dt~yargs --global --save

.ts ไฟล์

เพิ่มสิ่งนี้ลงในไฟล์. ts:

import { argv } from 'yargs';

...

  let debug: boolean = argv.debug;

สิ่งนี้จะต้องทำในไฟล์. ts แต่ละไฟล์แยกกัน (แม้แต่tools/tasks/projectไฟล์ที่นำเข้ามาในgulpfile.ts/js )

วิ่ง

gulp build.dev --debug

หรือnpmผ่านการผ่าน ARG เพื่ออึก:

npm run build.dev -- --debug

2

ส่งผ่านอาร์กิวเมนต์จากบรรทัดคำสั่ง

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

จากนั้นเรียกใช้อึกด้วย:

$ gulp scripts --env development

แหล่ง


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

CLI gulp productionเรียกใช้งานการผลิตของฉันและตั้งค่าสถานะสำหรับเงื่อนไขใด ๆ


1

เราต้องการที่จะผ่านไฟล์ config ที่แตกต่างกันสำหรับสภาพแวดล้อมที่แตกต่างกัน - หนึ่งสำหรับการผลิต , devและการทดสอบ นี่คือรหัสในไฟล์อึก:

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

นี่คือรหัสในไฟล์ 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);
    }

และจากนั้นเรียกใช้มันอึก --env=testing


1

เวลาผ่านไปแล้วตั้งแต่คำถามนี้ถูกโพสต์ แต่อาจจะช่วยใครซักคน

ฉันใช้ GULP CLI 2.0.1 (ติดตั้งทั่วโลก) และ GULP 4.0.0 (ติดตั้งในเครื่อง) ที่นี่เป็นวิธีที่คุณทำได้โดยไม่ต้องใช้ปลั๊กอินเพิ่มเติม ฉันคิดว่ารหัสค่อนข้างอธิบายตนเอง

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;

และเรียกใช้จากคอนโซล:

gulp availableTasks

จากนั้นเรียกใช้และดูความแตกต่าง:

gulp availableTasks --verbose
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.