Reputation: 6888
Normally in Gulp tasks look like this:
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));
});
Is it possible to pass a command line flag to gulp (that's not a task) and have it run tasks conditionally based on that? For instance
$ gulp my-task -a 1
And then in my 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));
});
Upvotes: 379
Views: 158329
Reputation: 1170
We wanted to pass a different config file for different environments -- one for production, dev and testing. This is the code in the gulp file:
//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;
}
This is the code in the app.js file:
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);
}
And then to run it gulp --env=testing
Upvotes: 1
Reputation: 301
It has been some time since this question has been posted, but maybe it will help someone.
I am using GULP CLI 2.0.1 (installed globally) and GULP 4.0.0 (installed locally) here is how you do it without any additional plugin. I think the code is quite self-explanatory.
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;
And run from the console:
gulp availableTasks
Then run and see the differences:
gulp availableTasks --verbose
Upvotes: 1
Reputation: 7018
Edit
gulp-util
is deprecated and should be avoid, so it's recommended to use minimist instead, which gulp-util
already used.
So I've changed some lines in my gulpfile to remove gulp-util
:
var argv = require('minimist')(process.argv.slice(2));
gulp.task('styles', function() {
return gulp.src(['src/styles/' + (argv.theme || 'main') + '.scss'])
…
});
Original
In my project I use the following flag:
gulp styles --theme literature
Gulp offers an object gulp.env
for that. It's deprecated in newer versions, so you must use gulp-util for that. The tasks looks like this:
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' }));
});
The environment setting is available during all subtasks. So I can use this flag on the watch task too:
gulp watch --theme literature
And my styles task also works.
Ciao Ralf
Upvotes: 105
Reputation: 9669
And if you are using typescript (gulpfile.ts
) then do this for yargs
(building on @Caio Cunha's excellent answer https://stackoverflow.com/a/23038290/1019307 and other comments above):
npm install --save-dev yargs
typings install dt~yargs --global --save
.ts
filesAdd this to the .ts files:
import { argv } from 'yargs';
...
let debug: boolean = argv.debug;
This has to be done in each .ts file individually (even the tools/tasks/project
files that are imported into the gulpfile.ts/js
).
gulp build.dev --debug
Or under npm
pass the arg through to gulp:
npm run build.dev -- --debug
Upvotes: 4
Reputation: 33438
If you've some strict (ordered!) arguments, then you can get them simply by checking process.argv
.
var args = process.argv.slice(2);
if (args[0] === "--env" && args[1] === "production");
Execute it: gulp --env production
...however, I think that this is tooo strict and not bulletproof! So, I fiddled a bit around... and ended up with this utility function:
function getArg(key) {
var index = process.argv.indexOf(key);
var next = process.argv[index + 1];
return (index < 0) ? null : (!next || next[0] === "-") ? true : next;
}
It eats an argument-name and will search for this in process.argv
. If nothing was found it spits out null
. Otherwise if their is no next argument or the next argument is a command and not a value (we differ with a dash) true
gets returned. (That's because the key exist, but there's just no value). If all the cases before will fail, the next argument-value is what we get.
> 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
Ok, enough for now... Here's a simple example using 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"));
});
Run it gulp --env production
Upvotes: 36
Reputation: 404
var isProduction = (process.argv.indexOf("production")>-1);
CLI gulp production
calls my production task and sets a flag for any conditionals.
Upvotes: 2
Reputation: 1429
Here's a quick recipe I found:
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
Original Ref (not available anymore): https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-params-from-cli.md
From Updated Ref: https://github.com/gulpjs/gulp/blob/master/docs/recipes/pass-arguments-from-cli.md
// 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
Upvotes: 58
Reputation: 37673
There's a very simple way to do on/off
flags without parsing the arguments. gulpfile.js
is just a file that's executed like any other, so you can do:
var flags = {
production: false
};
gulp.task('production', function () {
flags.production = true;
});
And use something like gulp-if
to conditionally execute a step
gulp.task('build', function () {
gulp.src('*.html')
.pipe(gulp_if(flags.production, minify_html()))
.pipe(gulp.dest('build/'));
});
Executing gulp build
will produce a nice html, while gulp production build
will minify it.
Upvotes: 40
Reputation: 29816
// 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'));
});
Then run gulp with:
$ gulp scripts --env development
Upvotes: 2
Reputation: 238
I built a plugin to inject parameters from the commandline into the task callback.
gulp.task('mytask', function (production) {
console.log(production); // => true
});
// gulp mytask --production
https://github.com/stoeffel/gulp-param
If someone finds a bug or has a improvement to it, I am happy to merge PRs.
Upvotes: 7
Reputation: 23394
Gulp doesn't offer any kind of util for that, but you can use one of the many command args parsers. I like yargs
. Should be:
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));
});
You can also combine it with gulp-if
to conditionally pipe the stream, very useful for dev vs. prod building:
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/'));
});
And call with gulp my-js-task
or gulp my-js-task --production
.
Upvotes: 531