是否可以将标志传递给Gulp以使其以不同方式运行任务?

aso*_*erg 365 javascript node.js 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));
});
Run Code Online (Sandbox Code Playgroud)

是否可以将命令行标志传递给gulp(这不是任务)并让它根据具体条件运行任务?例如

$ gulp my-task -a 1
Run Code Online (Sandbox Code Playgroud)

然后在我的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));
});
Run Code Online (Sandbox Code Playgroud)

Cai*_*nha 524

Gulp不提供任何类型的util,但你可以使用众多命令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));
});
Run Code Online (Sandbox Code Playgroud)

您还可以将它与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/'));
});
Run Code Online (Sandbox Code Playgroud)

gulp my-js-task或打电话gulp my-js-task --production.

  • 这应该以某种方式提到@官方gulp github,必不可少的东西! (44认同)
  • 如果你使用`npm run gulp`那么你应该像`npm run gulp - --production`一样使用它. (12认同)
  • 嗨@plankguy,视频非常好.谢谢.它展示了如何手动解析环境变量,没有任何lib.一个小的区别是视频是关于*环境变量*,而上面的例子是关于*命令行参数*,其中Yargs是另一个有助于通过抽象变量解析来简化消耗的工具. (9认同)
  • 这是[官方gulp github](https://github.com/gulpjs/gulp/blob/master/docs/CLI.md#task-specific-flags)(字面意思). (3认同)
  • 这个视频解释了如何在没有yargs的情况下实现这一目标:https://www.youtube.com/watch?v = gRzCAyNrPV8 (2认同)

RWA*_*WAM 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'])
    …
});
Run Code Online (Sandbox Code Playgroud)

原版的

在我的项目中,我使用以下标志:

gulp styles --theme literature
Run Code Online (Sandbox Code Playgroud)

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' }));
});
Run Code Online (Sandbox Code Playgroud)

所有子任务期间都可以使用环境设置.所以我也可以在监视任务上使用这个标志:

gulp watch --theme literature
Run Code Online (Sandbox Code Playgroud)

我的风格任务也有效.

Ciao Ralf

  • `gulp-util`利用`minimist`库进行命令行参数解析.因此,如果您正在使用`gulp-util`,则不需要为此目的使用额外的库.文件:https://github.com/substack/minimist (9认同)
  • [`gulp.env`已被弃用](https://github.com/gulpjs/gulp/blob/master/CHANGELOG.md#35),正如您在运行时可以通过控制台日志消息看到的那样.他们要求您使用自己的解析器并建议`yargs`或`minimist`. (6认同)
  • 你可以缩短`util.env.theme?util.env.theme:'main'到`util.env.theme || "main'`.无论如何+1. (4认同)
  • 谢谢@CaioToOn的提示.我也更新了我的答案和我的项目;) (2认同)

AEQ*_*AEQ 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'));
});
Run Code Online (Sandbox Code Playgroud)

CLI

gulp scripts --env production
Run Code Online (Sandbox Code Playgroud)

Original Ref(不再提供):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'));
});
Run Code Online (Sandbox Code Playgroud)

CLI

gulp scripts --env production
Run Code Online (Sandbox Code Playgroud)

  • 那个食谱链接现在似乎消失了.还有一个使用minimist包代替:[pass-arguments-from-cli.md](https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli .MD).这是有道理的,因为gulp本身[使用最小化](https://github.com/gulpjs/gulp/blob/master/package.json#L27). (2认同)

Emi*_*nov 39

有一种非常简单的方法可以在on/off不解析参数的情况下执行标记.gulpfile.js只是一个像其他文件一样执行的文件,所以你可以这样做:

var flags = {
  production: false
};

gulp.task('production', function () {
  flags.production = true;
});
Run Code Online (Sandbox Code Playgroud)

并使用类似gulp-if条件执行步骤的东西

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

执行gulp build将产生一个漂亮的HTML,同时gulp production build将缩小它.

  • 这种方法的缺点是每次要更改标志变量时都必须更改gulpfile.js,而不是仅仅在终端中将参数传递给gulp命令. (3认同)
  • 好主意,使用yargs保存,我通过设置vars的'pre-production'任务扩展了这个,然后'production'有一个依赖数组['build','pre-production'].这样你就可以运行'gulp production'. (2认同)

yck*_*art 33

如果你有一些严格的(有序的!)参数,那么你可以通过检查来获得它们process.argv.

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

if (args[0] === "--env" && args[1] === "production");
Run Code Online (Sandbox Code Playgroud)

执行它: 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;
}
Run Code Online (Sandbox Code Playgroud)

它吃一个参数名称,并将在其中搜索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
Run Code Online (Sandbox Code Playgroud)

好的,现在已经足够......这是一个使用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"));
});
Run Code Online (Sandbox Code Playgroud)

运行 gulp --env production


sto*_*fel 7

我构建了一个插件,用于将命令行中的参数注入任务回调.

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

// gulp mytask --production
Run Code Online (Sandbox Code Playgroud)

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

如果有人发现了错误或对其有所改进,我很乐意合并PR.