将参数传递给 Gulp 任务

Posted

技术标签:

【中文标题】将参数传递给 Gulp 任务【英文标题】:Pass Parameter to Gulp Task 【发布时间】:2015-04-16 19:34:50 【问题描述】:

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

【问题讨论】:

github.com/gulpjs/gulp/blob/master/docs/recipes/… 这能回答你的问题吗? Is it possible to pass a flag to Gulp to have it run tasks in different ways? 【参考方案1】:

当然有一个更短的符号,但这是我的方法:

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)设置 env:

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

附:对于日志,我添加了以下内容:

  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 () 
    ));

欢迎提出优化建议。

【讨论】:

【参考方案2】:

这是一个功能程序不能没有。你可以试试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。还有另一个帖子,其中有 yargs 和 minimist 的好例子:(Is it possible to pass a flag to Gulp to have it run tasks in different ways?)

【讨论】:

答案写得真好,谢谢你的例子! 如何在 javascript 中访问它? 如果您将 gulp 与 yargs 一起使用,请注意以下事项: 如果您有一个任务 'customer' 并且不想使用 yargs build in 参数检查所需命令:command("customer","Create客户目录") 如果您想使用 yargs 内置参数检查所需的“命令”以及 gulp,请参阅下面的评论:***.com/a/41412558/1256697 (argv.production === undefined) ? false : true; 等价于argv.production !== undefined【参考方案3】:

如果你想使用环境参数和其他工具如日志,你可以使用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-util 自 2016 年起已弃用【参考方案4】:

我知道我回答这个问题迟到了,但我想补充一下@Ethan 的回答,这是投票率最高且被接受的答案。

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

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

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

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

.alias(key, 别名)

将密钥名称设置为等效项,以便传播对密钥的更新 别名,反之亦然。

可选的 .alias() 可以采用将键映射到别名的对象。每个 此对象的键应该是选项的规范版本,并且 每个值都应该是一个字符串或一个字符串数组。

【讨论】:

【参考方案5】:

这是另一种无需额外模块的方式:

我需要根据任务名称猜测环境,我有一个“开发”任务和一个“生产”任务。

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

为此,我只检查正在运行的任务名称:

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

【讨论】:

【参考方案6】:

如果你使用 gulp 和 yargs, 请注意以下几点:

如果您有一个任务“客户”并且不想使用 yargs build in 参数检查所需的命令:

.command("customer &lt;place&gt; [language]","Create a customer directory") 调用它:

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

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

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

.command("customer1 &lt;place&gt; [language]","Create a customer directory")

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

希望对你有帮助..

【讨论】:

【参考方案7】:

如果您想避免添加额外的依赖项,我发现节点的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

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

【讨论】:

"var option, i = process,argv.indexOf("--option");"中有一个错字。我认为应该是 proccess.argv。 啊,应该这样。已更正。谢谢@luis 我只是想检查 --dev 标志,以便区分生产环境和低级环境。这可以在不添加额外依赖项的情况下解决问题。谢谢! 对我来说,gulp myTask --production 的结果是 process.argv 等于 [pathToNode, pathToGulp, 'myTask', '--production'] 它可能已经改变了,我见过一些具有相同差异的旧示例。无论如何,您可以调试它并查看您的情况。这应该是公认的答案,因为它具有零依赖性..【参考方案8】:

将参数传递给 gulp 可能意味着一些事情:

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

这是一种将参数从主 gulpfile 传递到 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 任务并希望向它们传递一些方便的环境配置,这可能会派上用场。我不确定它是否可以在一项任务和另一项任务之间工作。

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

有一个官方的 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

配方中有更完整的信息。

【讨论】:

为什么列表顶部的垃圾和底部的正确解决方案没有得到支持?叹息【参考方案11】:

这是我如何使用它的示例。对于 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);
);

【讨论】:

【参考方案12】:

@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 可能会给你一些其他的想法。

【讨论】:

以上是关于将参数传递给 Gulp 任务的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 中使用环境将参数传递给 Rake 任务? [复制]

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

将 VB 函数回调作为参数传递给 .NET

通过javascript将参数传递给动作不会传递整数值

将参数传递给windows计划任务

如何将命名参数传递给 Rake 任务?