将参数传递给 Gulp 任务

Pass Parameter to Gulp Task

通常我们可以 运行 gulp 通过类似 gulp mytask 的方式从控制台执行任务。无论如何,我可以将参数传递给 gulp 任务吗?如果可能,请举例说明如何完成。

这是一个功能程序离不开的东西。你可以试试 yargs.

npm install --save-dev yargs

你可以这样使用它:

gulp mytask --production --test 1234

在代码中,例如:

var argv = require('yargs').argv;
var isProduction = (argv.production === undefined) ? false : true;

供您理解:

> gulp watch
console.log(argv.production === undefined);  <-- true
console.log(argv.test === undefined);        <-- true

> gulp watch --production
console.log(argv.production === undefined);  <-- false
console.log(argv.production);                <-- true
console.log(argv.test === undefined);        <-- true
console.log(argv.test);                      <-- undefined

> gulp watch --production --test 1234
console.log(argv.production === undefined);  <-- false
console.log(argv.production);                <-- true
console.log(argv.test === undefined);        <-- false
console.log(argv.test);                      <-- 1234

希望你能从这里开始。

您可以使用另一个插件,minimist。还有另一个 post,其中有 yargs 和 minimist 的很好的例子:(Is it possible to pass a flag to Gulp to have it run tasks in different ways?)

@Ethan 的回答完全有效。根据我的经验,更多节点的方式是使用环境变量。这是配置部署在托管平台(例如 Heroku 或 Dokku)上的程序的标准方法。

要从命令行传递参数,请这样做:

发展: gulp dev

制作: NODE_ENV=production gulp dev

语法不同,但很Unix,兼容Heroku、Dokku等

您可以在代码中访问变量 process.env.NODE_ENV

MYAPP=something_else gulp dev

会设置

process.env.MYAPP === 'something_else'

This answer 可能会给你一些其他的想法。

这是我的使用示例。对于 css/less 任务。所有人都可以申请。

var cssTask = function (options) {
  var minifyCSS = require('gulp-minify-css'),
    less = require('gulp-less'),
    src = cssDependencies;

  src.push(codePath + '**/*.less');

  var run = function () {
    var start = Date.now();

    console.log('Start building CSS/LESS bundle');

    gulp.src(src)
      .pipe(gulpif(options.devBuild, plumber({
        errorHandler: onError
      })))
      .pipe(concat('main.css'))
      .pipe(less())
      .pipe(gulpif(options.minify, minifyCSS()))
      .pipe(gulp.dest(buildPath + 'css'))
      .pipe(gulpif(options.devBuild, browserSync.reload({stream:true})))
      .pipe(notify(function () {
        console.log('END CSS/LESS built in ' + (Date.now() - start) + 'ms');
      }));
  };

  run();

  if (options.watch) {
    gulp.watch(src, run);
  }
};

gulp.task('dev', function () {
  var options = {
    devBuild: true,
    minify: false,
    watch: false
  };

  cssTask (options);
});

有官方的 gulp 食谱,使用 minimist

https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli.md

基础知识是使用 minimist 来分离 cli 参数并将它们与已知选项组合:

var options = minimist(process.argv.slice(2), knownOptions);

这会解析类似

的内容
$ gulp scripts --env development

食谱中有更完整的信息。

只需将其加载到进程中的新对象中.. process.gulp = {} 并让任务在那里查看。

如果您想避免添加额外的依赖项,我发现节点的 process.argv 很有用:

gulp.task('mytask', function() {
    console.log(process.argv);
});

所以如下:

gulp mytask --option 123

应该显示:

[ 'node', 'path/to/gulp.js', 'mytask', '--option', '123']

如果您确定所需参数位于正确位置,则不需要标志。**只需使用(在本例中):

var option = process.argv[4]; //set to '123'

但是:由于选项可能未设置,或者可能处于不同的位置,我觉得更好的主意是:

var option, i = process.argv.indexOf("--option");
if(i>-1) {
    option = process.argv[i+1];
}

这样,您就可以处理多个选项的变化,例如:

//task should still find 'option' variable in all cases
gulp mytask --newoption somestuff --option 123
gulp mytask --option 123 --newoption somestuff
gulp mytask --flag --option 123

** 编辑:对于节点脚本是正确的,但是 gulp 将没有前导“--”的任何内容解释为另一个任务名称。所以使用 gulp mytask 123 会失败,因为 gulp 找不到名为“123”的任务。

如果你想使用环境参数和其他工具,比如日志,你可以使用gulp-util

/* 
  $npm install gulp-util --save-dev
  $gulp --varName 123
*/
var util = require('gulp-util');
util.log(util.env.varName);

更新

gulp-util 现已弃用。您可以改用 minimist

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

将参数传递给 gulp 可能意味着以下几点:

  • 从命令行到 gulp文件(已在此处举例说明)。
  • 从 gulpfile.js 脚本主体到 gulp 任务。
  • 从一个 gulp 任务到另一个 gulp 任务。

这是一种将参数从主 gulp 文件传递​​到 gulp 任务的方法。通过将需要参数的任务移动到它自己的模块并将其包装在函数中(因此可以传递参数)。:

// ./gulp-tasks/my-neat-task.js file
module.exports = function(opts){

  opts.gulp.task('my-neat-task', function(){
      console.log( 'the value is ' + opts.value );
  });

};
//main gulpfile.js file

//...do some work to figure out a value called val...
var val = 'some value';

//pass that value as a parameter to the 'my-neat-task' gulp task
require('./gulp-tasks/my-neat-task.js')({ gulp: gulp, value: val});

如果您有很多 gulp 任务并想向它们传递一些方便的环境配置,这会派上用场。我不确定它是否可以在一个任务和另一个任务之间工作。

如果将 gulp 与 yargs 一起使用, 请注意以下事项:

如果您有任务 'customer' 并且不想使用 yargs build in Parameter checking for required commands:

.command("customer <place> [language]","Create a customer directory") 调用它:

gulp customer --customer Bob --place Chicago --language english

yargs 总是会抛出一个错误,即没有足够的命令分配给调用,即使您有!! —

尝试一下,只在命令中添加一个数字(使其不等于 gulp-任务名称)...它会起作用:

.command("customer1 <place> [language]","Create a customer directory")

这是因为 gulp 似乎在 yargs 能够检查此必需参数之前触发任务。弄清楚这一点花了我几个小时。

希望这对你有帮助..

这是另一种没有额外模块的方法:

我需要根据任务名称猜测环境,我有一个 'dev' 任务和一个 'prod' 任务。

当我运行 gulp prod 应该设置为生产环境。 当我 运行 gulp dev 或其他任何东西时,它应该设置为开发环境。

为此,我只检查 运行ning 任务名称:

devEnv = process.argv[process.argv.length-1] !== 'prod';

我知道我回答这个问题来晚了,但我想补充一些内容来回答@Ethan,这是投票最高和被接受的答案。

我们可以使用 yargs 来获取命令行参数,并且我们还可以为一些参数添加我们自己的别名,如下所示。

var args = require('yargs')
    .alias('r', 'release')
    .alias('d', 'develop')
    .default('release', false)
    .argv;

请参阅此 link 了解更多详情。 https://github.com/yargs/yargs/blob/HEAD/docs/api.md

以下是 yargs 文档中给出的别名的使用。我们还可以在那里找到更多 yargs 功能,可以使命令行传递体验更好。

.alias(key, alias)

Set key names as equivalent such that updates to a key will propagate to aliases and vice-versa.

Optionally .alias() can take an object that maps keys to aliases. Each key of this object should be the canonical version of the option, and each value should be a string or an array of strings.

肯定有更短的表示法,但那是我的方法:

gulp.task('check_env', function () {
  return new Promise(function (resolve, reject) {
    // gulp --dev
    var env = process.argv[3], isDev;
    if (env) {
      if (env == "--dev") {
        log.info("Dev Mode on");
        isDev = true;
      } else {
        log.info("Dev Mode off");
        isDev = false;
      }
    } else {
      if (variables.settings.isDev == true) {
        isDev = true;
      } else {
        isDev = false;
      }
    }
    resolve();
  });
});

如果要根据实际 Git 分支 (master/develop) 设置环境:

gulp.task('set_env', function (cb) {
  exec('git rev-parse --abbrev-ref HEAD', function (err, stdout, stderr) {
    const git__branch = stdout.replace(/(\r\n|\n|\r)/gm, ""),
          regex__feature = new RegExp('feature/feature-*');

    if (git__branch == "develop") {
      log.info("‍Develop Branch");
      isCompressing = false;
    } else if (git__branch == "master") {
      log.info("Master Branch");
      isCompressing = true;
    } else if (regex__feature.test(git__branch) === true){
      log.info("✨Feature Branch");
      isCompressing = true;
    }else{

      //TODO: check for other branch
      log.warn("Unknown " + git__branch + ", maybe hotfix?");
      //isCompressing = variables.settings.isCompressing;
    }
    log.info(stderr);
    cb(err);
  });
  return;
})

P.s。对于日志,我添加了以下内容:

  var log = require('fancy-log');

如果你需要它,那是我的默认任务:

gulp.task('default',
  gulp.series('set_env', gulp.parallel('build_scss', 'minify_js', 'minify_ts', 'minify_html', 'browser_sync_func', 'watch'),
    function () {
    }));

欢迎提出优化建议。