将参数传递给Gulp任务

时间:2015-02-16 10:07:20

标签: gulp

通常我们可以通过像gulp mytask之类的东西从控制台运行gulp任务。反正我是否可以将参数传递给gulp任务?如果可能,请举例说明如何完成。

12 个答案:

答案 0 :(得分:243)

一个功能程序不能没有。你可以试试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

希望你能从这里拿走它。

你可以使用另一个插件,即最小化。还有另一个帖子,其中有yargs和minimist的优秀例子:( Is it possible to pass a flag to Gulp to have it run tasks in different ways?

答案 1 :(得分:125)

如果您想避免添加额外的依赖项,我发现节点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会解释任何没有前导&#34; - &#34;作为另一个任务名称。因此,使用gulp mytask 123会失败,因为gulp无法找到名为&#39; 123&#39;

的任务

答案 2 :(得分:17)

将参数传递给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任务并希望通过它们一些方便的环境配置,这可以派上用场。我不确定它是否可以在一个任务和另一个任务之间起作用。

答案 3 :(得分:14)

使用minimist有一个正式的吞食方法。

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

基础知识是使用最小化来分离cli参数并将它们与已知选项结合起来:

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

哪个会解析类似

的内容
$ gulp scripts --env development

食谱中有更完整的信息。

答案 4 :(得分:14)

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

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

答案 5 :(得分:5)

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

答案 6 :(得分:4)

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

答案 7 :(得分:2)

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

我需要从任务名称猜测环境,我有'dev'任务和'prod'任务。

当我运行gulp prod时,应将其设置为prod环境。 当我运行gulp dev或其他任何内容时,应将其设置为开发环境。

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

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

答案 8 :(得分:1)

如果您使用 gulp with yargs,,请注意以下事项:

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

class DatetimeIndex: ... dayofweek = _field_accessor('dayofweek', 'dow', "The day of the week with Monday=0, Sunday=6") weekday = dayofweek 称之为:

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

yargs将总是抛出一个错误,即使你已经为调用分配了足够的命令! -

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

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

这是gulp似乎触发任务的原因,之前yargs能够检查这个必需的参数。我花了几个小时来解决这个问题。

希望这可以帮助你..

答案 9 :(得分:0)

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

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

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)

     

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

     

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

答案 10 :(得分:0)

当然有一个简短的表示法,但这是我的方法:

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) {
    git__branch = stdout.replace(/(\r\n|\n|\r)/gm, "");
    if (git__branch == "develop") {
      log.info("?‍?Develop Branch");
      isCompressing = false;
    } else if (git__branch == "master") {
      log.info("?Master Branch");
      isCompressing = true;
    } else {
      //TODO: check for feature-* branch
      log.warn("Unknown " + git__branch + ", maybe feat?");
      //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 () {
    }));

欢迎提出优化建议。

答案 11 :(得分:-2)

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