Можно ли передать флаг в Gulp, чтобы он запускал задачи по-разному?

Обычно в 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 (это не задача) и запустить ли он задачи условно на основе этого? Например,

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

Ответ 1

Gulp для этого не предлагает никакого использования, но вы можете использовать один из многих парсеров команд args. Мне нравится 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 и 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/'));
});

И вызовите с помощью gulp my-js-task или gulp my-js-task --production.

Ответ 2

В моем проекте я использую следующий флаг:

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

И моя задача стилей также работает.

Ciao Ralf

Ответ 3

Вот быстрый рецепт, который я нашел:

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

Альтернатива с минималистским

Из обновленного 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

Ответ 4

Там очень простой способ сделать 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 уменьшит его.

Ответ 5

Если у вас есть строгие (упорядоченные!) аргументы, вы можете получить их просто, проверив 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

Хорошо, достаточно сейчас... Вот простой пример с использованием 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

Ответ 6

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

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

// gulp mytask --production

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

Если кто-то находит ошибку или имеет улучшение, я рад объединить PR.

Ответ 7

И если вы используете typescript (gulpfile.ts), сделайте это для yargs (построив на @Caio Cunha отличный ответ fooobar.com/questions/19643/... и другие комментарии выше):

Установка

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).

Run

gulp build.dev --debug

Или в npm передать arg через gulp:

npm run build.dev -- --debug

Ответ 8

Передача аргументов из командной строки

// 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 с помощью:

$ gulp scripts --env development

Источник

Ответ 9

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

CLI gulp production вызывает мою производственную задачу и устанавливает флаг для любых условных обозначений.

Ответ 10

Мы хотели передать другой файл конфигурации для разных сред - один для производства, dev и тестирования. Это код в файле 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;
}