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

IT技术 javascript node.js gulp
2021-01-22 04:13:32

通常在 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));
});
6个回答

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

如果你使用,npm run gulp那么你应该像npm run gulp -- --production.
2021-03-18 04:13:32
@the official gulp github(字面意思)提到了这一点
2021-03-20 04:13:32
这应该以某种方式提到@the official gulp github,必不可少的东西!
2021-03-28 04:13:32
嗨@plankguy,视频非常好。谢谢。它展示了如何在没有任何库的情况下手动解析环境变量。一个小的区别是视频是关于环境变量的,而上面的例子是关于命令行参数的,其中 Yargs 是另一个通过抽象变量解析来帮助简化消耗的工具。
2021-03-29 04:13:32
这个,视频解释了如何在没有 yargs 的情况下实现这一目标:youtube.com/watch? v=gRzCAyNrPV8
2021-04-10 04:13:32

编辑

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

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

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

gulp watch --theme literature

我的样式任务也有效。

乔拉尔夫

您可以缩短util.env.theme ? util.env.theme : 'main'util.env.theme || 'main'. 无论如何+1。
2021-03-15 04:13:32
gulp.env正在被弃用,您可以在运行它时通过控制台日志消息看到。他们要求您使用自己的解析器并建议yargsminimist
2021-03-18 04:13:32
感谢@CaioToOn 的提示。我也更新了我的答案和我的项目;)
2021-04-10 04:13:32
gulp-util利用minimist库进行命令行参数解析。因此,如果您正在使用gulp-util,则不需要为此目的额外的库。文档:github.com/substack/minimist
2021-04-11 04:13:32

这是我找到的一个快速食谱:

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

命令行界面

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

命令行界面

gulp scripts --env production
那个食谱链接现在似乎不见了。还有另一个使用 minimist 包代替:pass-arguments-from-cli.md这是有道理的,因为gulp本身使用 minimist
2021-03-21 04:13:32

有一种非常简单的方法可以在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将缩小它。

我认为这是做到这一点的gulp方式
2021-03-14 04:13:32
好主意,使用 yargs 保存,我通过设置变量的“预生产”任务扩展了它,然后“生产”具有 ['build','pre-production'] 的依赖数组。这样你就可以运行'gulp production'。
2021-03-20 04:13:32
好的!我在设置流之前使用它,gulp.task('mytask', function() { if (flags.myflag ) { flaggedtask } else { unflaggedask } });
2021-03-25 04:13:32
这种方法的缺点是每次要更改标志变量时都必须更改 gulpfile.js,而不仅仅是将参数传递给终端中的 gulp 命令。
2021-04-01 04:13:32
@Keegan'shairstyle82 我做了类似的事情,但必须利用运行序列来确保在设置flags.
2021-04-09 04:13:32

如果您有一些严格的(有序的!)参数,那么您可以通过检查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,则返回。(那是因为密钥存在,但没有value)。如果之前的所有情况都失败,则下一个参数值就是我们得到的。

> 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

@yckart - 您可能应该在代码示例中为 getArg 添加 require('..') 。
2021-03-19 04:13:32
参数名称应以 dash(es): 为前缀if (args[0] === '--env' && args[1] === 'production');,至少在 gulp 3.8.11 中
2021-04-01 04:13:32