是否可以将标志传递给 Gulp 以使其以不同的方式运行任务?
Posted
技术标签:
【中文标题】是否可以将标志传递给 Gulp 以使其以不同的方式运行任务?【英文标题】:Is it possible to pass a flag to Gulp to have it run tasks in different ways? 【发布时间】:2014-05-26 06:17:03 【问题描述】:通常在 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));
);
【问题讨论】:
因为它在节点中运行,您可能可以使用process.argv
来访问命令行参数。
【参考方案1】:
这个问题发布已经有一段时间了,但也许它会对某人有所帮助。
我正在使用 GULP CLI 2.0.1(全局安装)和 GULP 4.0.0(本地安装),这是您在没有任何额外插件的情况下如何做到的。我认为代码是不言自明的。
var cp = require('child_process'),
src, dest, series, parallel, watch = require('gulp');
// == availableTasks: log available tasks to console
function availableTasks(done)
var command = 'gulp --tasks-simple';
if (process.argv.indexOf('--verbose') > -1)
command = 'gulp --tasks';
cp.exec(command, function(err, stdout, stderr)
done(console.log('Available tasks are:\n' + stdout));
);
availableTasks.displayName = 'tasks';
availableTasks.description = 'Log available tasks to console as plain text list.';
availableTasks.flags =
'--verbose': 'Display tasks dependency tree instead of plain text list.'
;
exports.availableTasks = availableTasks;
并从控制台运行:
gulp availableTasks
然后运行看看有什么不同:
gulp availableTasks --verbose
【讨论】:
【参考方案2】:编辑
gulp-util
是deprecated 应该避免使用,所以建议使用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
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' ));
);
环境设置在所有子任务期间都可用。所以我也可以在监视任务上使用这个标志:
gulp watch --theme literature
我的样式任务也有效。
Ciao 拉尔夫
【讨论】:
gulp.env
is being deprecated,正如您在运行它时从控制台日志消息中看到的那样。他们要求您使用自己的解析器并建议 yargs
或 minimist
。
感谢@CaioToOn 的提示。我也更新了我的答案和我的项目;)
您可以将util.env.theme ? util.env.theme : 'main'
缩短为util.env.theme || 'main'
。无论如何+1。
gulp-util
利用minimist
库进行命令行参数解析。因此,如果您使用gulp-util
,则不需要为此目的使用额外的库。文档:github.com/substack/minimist【参考方案3】:
如果您使用的是打字稿 (gulpfile.ts
),请为 yargs
执行此操作(基于 @Caio Cunha 的出色回答 https://***.com/a/23038290/1019307 和上述其他 cmets):
安装
npm install --save-dev yargs
typings install dt~yargs --global --save
.ts
文件
将此添加到 .ts 文件中:
import argv from 'yargs';
...
let debug: boolean = argv.debug;
这必须在每个 .ts 文件中单独完成(即使是导入到 gulpfile.ts/js
中的 tools/tasks/project
文件)。
运行
gulp build.dev --debug
或在npm
下将arg 传递给gulp:
npm run build.dev -- --debug
【讨论】:
【参考方案4】:我们希望为不同的环境传递不同的配置文件——一个用于生产、dev和测试。这是 gulp 文件中的代码:
//passing in flag to gulp to set environment
//var env = gutil.env.env;
if (typeof gutil.env.env === 'string')
process.env.NODE_ENV = gutil.env.env;
这是 app.js 文件中的代码:
if(env === 'testing')
var Config = require('./config.testing.js');
var Api = require('./api/testing.js')(Config.web);
else if(env === 'dev')
Config = require('./config.dev.js');
Api = require('./api/dev.js').Api;
else
Config = require('./config.production.js');
Api = require('./api/production.js')(Config.web);
然后运行它 gulp --env=testing
【讨论】:
【参考方案5】:如果您有一些严格的(有序的!)参数,那么您只需检查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
将返回。 (那是因为密钥存在,但没有价值)。如果之前的所有情况都失败了,那么下一个参数值就是我们得到的。
> 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
【讨论】:
参数名称应以破折号为前缀:if (args[0] === '--env' && args[1] === 'production');
,至少在 gulp 3.8.11 中
@yckart - 您可能应该在代码示例中为 getArg 添加 require('..')。【参考方案6】:
var isProduction = (process.argv.indexOf("production")>-1);
CLI gulp production
调用我的生产任务并为任何条件设置一个标志。
【讨论】:
【参考方案7】:这是我找到的快速食谱:
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
极简主义的替代品
来自更新的参考: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 本身 uses minimist.【参考方案8】:有一种非常简单的方法可以在不解析参数的情况下执行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
会缩小它。
【讨论】:
好主意,使用 yargs 保存,我通过设置变量的“预生产”任务扩展了这一点,然后“生产”具有 ['build','pre -生产']。这样你就可以运行“gulp production”。 不错!我在设置流之前使用它,gulp.task('mytask', function() if (flags.myflag ) flaggedtask else unflaggedask );
我认为这是吞咽的方式
@Keegan'shairstyle82 我做了类似的事情,但必须使用run-sequence 来确保在设置flags
的属性时没有竞争条件。
这种方法的缺点是每次要更改标志变量时都必须更改 gulpfile.js,而不是只在终端中将参数传递给 gulp 命令。【参考方案9】:
从命令行传递参数
// 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 in production
.pipe(gulp.dest('dist'));
);
然后运行 gulp:
$ gulp scripts --env development
Source
【讨论】:
【参考方案10】:我构建了一个插件,将命令行中的参数注入到任务回调中。
gulp.task('mytask', function (production)
console.log(production); // => true
);
// gulp mytask --production
https://github.com/stoeffel/gulp-param
如果有人发现错误或对其进行了改进,我很乐意合并 PR。
【讨论】:
【参考方案11】:Gulp 没有为此提供任何类型的实用程序,但您可以使用许多命令 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));
);
您还可以将它与 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
。
【讨论】:
这应该以某种方式提到@官方 gulp github,必不可少的东西! 这个,视频解释了如何在没有 yargs 的情况下实现这一点:youtube.com/watch?v=gRzCAyNrPV8 嗨@plankguy,视频非常好。谢谢。它展示了如何在没有任何库的情况下手动解析环境变量。一个小的区别是视频是关于环境变量的,而上面的例子是关于命令行参数的,其中Yargs是另一个工具,它通过抽象变量解析。 如果你使用npm run gulp
,那么你应该像npm run gulp -- --production
一样使用它。
这是@official gulp github 提到的(字面意思)。以上是关于是否可以将标志传递给 Gulp 以使其以不同的方式运行任务?的主要内容,如果未能解决你的问题,请参考以下文章
将参数传递给 UITapGestureRecognizer [重复]
是否可以创建同一对象的不同实例并通过将参数传递给 Koin 中的 get() 函数来访问它们?