Чи можна передати прапор Gulp, щоб він виконував завдання різними способами?


369

Зазвичай завдання Gulp виглядають так:

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

Gulp не пропонує для цього ніякої утиліти, але ви можете використовувати один з багатьох аналізаторів аргументів команд. Мені подобається 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щоб умовно прокласти потік, що дуже корисно для побудови розробок та продуктів:

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-taskабо gulp my-js-task --production.


45
Це слід якось згадати @ офіційний gulp github, необхідний матеріал!
Макс

2
Це відео пояснює, як цього досягти без ярдів: youtube.com/watch?v=gRzCAyNrPV8
plankguy

9
Привіт @plankguy, відео дуже приємне. Дякую. Він показує, як розібрати змінні середовища вручну, не маючи жодної ліб. Невелика різниця полягає в тому, що відео - це змінні середовища , тоді як приклад вище - про аргументи командного рядка , де Yargs - ще один інструмент, який допомагає спростити споживання шляхом абстрагування аналізу змінних змінних.
Caio Cunha

12
Якщо ви використовуєте, npm run gulpтоді ви повинні використовувати його як npm run gulp -- --production.
ivkremer

3
Про це згадується @ офіційний gulp github (буквально).
fracz

101

Редагувати

gulp-utilє застарілим і його слід уникати, тому рекомендується замість цього використовувати мінімаліст , який 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 пропонує об’єкт 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

І моє завдання стилів також працює.

Чіао Ральф


6
gulp.envзастаріла , як ви можете бачити повідомлення журналу консолі під час її запуску. Вони просять вас використовувати власний парсер і запропонувати yargsабо minimist.
Caio Cunha

2
Дякуємо @CaioToOn за ваш підказку. Я оновив свою відповідь і мій проект теж;)
RWAM

4
Можна скоротити util.env.theme ? util.env.theme : 'main'до util.env.theme || 'main'. У будь-якому разі +1.
Ренан

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

Альтернатива з мінімалізмом

З оновленого посилання: 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
Це посилання на рецепт, здається, вже пішло. Є ще один, який використовує натомість пакет мінімалізму : pass-arguments-from-cli.md . Це має сенс, оскільки сама глотка використовує мінімалізм .
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, я розширив це, маючи завдання "передвиробництва", яке встановлює vars, а потім "виробництво" має масив залежності ["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

... однак, я вважаю, що це занадто суворо і не куленепробивно! Отже, я трохи посварився ... і закінчив цю функцію утиліти:

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

Гаразд, достатньо зараз ... Ось простий приклад використання 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"));
});

Виконати його gulp --env production


Ім'я аргументу повинно бути префіксом тире (ів):, if (args[0] === '--env' && args[1] === 'production');принаймні, у глотці 3.8.11
piotr_cz

@yckart - вам, мабуть, слід додати вимогу ('..') для getArg у своєму прикладі коду.
jbyrd

7

Я створив плагін для введення параметрів з командного рядка в зворотний виклик завдань.

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

// gulp mytask --production

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

Якщо хтось знайде помилку або має покращення, я радий об'єднати PR.


4

А якщо ви використовуєте typecript ( 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 через gulp:

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

Ми хотіли передати інший конфігураційний файл для різних середовищ - один для виробництва , розробки та тестування . Це код у файлі 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;
}

Це код у файлі 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.