In the past I've used gulp.watch
to create a "watch" task which I use during development. In the "watch" task, I would have an individual watch which would just run whatever was needed. For example:
gulp.task("watch", function () {
gulp.watch("**/*.js", ["js"]);
gulp.watch("**/*.less", ["less"]);
});
And then a "build" task which would run everything together:
gulp.task("build", ["js", "less"]);
Works well, except it means that -ever- LESS file needs to be recompiled upon a single change, or every JS file for a single change.
I've switched to using gulp-watch
instead, so I can now have it do incremental builds. I now no longer have a "watch" task an instead have tasks that look like this:
gulp.task("less", function () {
return gulp.src("**/*.less")
.pipe(watch("**/*.less"))
.pipe(less())
.pipe(gulp.dest("dist"));
});
This works great for incremental builds, but now I can't figure out a clean way to have a "build" task which just builds without kicking it in to a watch-mode, for things such as deployments.
Question: Is there a standard/clean way for me to create a "build" task, without watching, without having to basically duplicate all of my tasks?
The solution I ended up coming up with is to use a global debug
value, which is set to true
normally, but the build
task sets to it false. Then, in the tasks, watch
is only added to the pipe if debug == true
.
Example:
var gulp = require('gulp'),
runSequence = require('run-sequence'),
watch = require('gulp-watch');
var debug = true;
gulp.task('copy', function () {
var task = gulp.src('**/*.js');
debug && task.pipe(watch());
task.pipe(gulp.dest('dist'));
});
gulp.task('build:dev', ['copy']);
gulp.task('build', function (cb) {
debug = false;
runSequence('build:dev', cb);
});
If I run build:dev
, it'll run copy
and put copy in to watch mode, because watch is piped on because the global debug
value is true
.
If I run build
, it sets the global debug
value to false
, so the watch isn't piped in, meaning it will just do the task without watching.
I can also add things only for debug == false
as well (like, uglifying).
This isn't super clean and doesn't fit super well with the gulp philosophy, but it works reasonably well, so I'm satisfied with it.
=========
I've started playing with Gulp 4.0 lately, and you now can't use runSequence (or at the very least, it's redundant), so you can't set the variable then call runSequence. What I ended up doing instead was creating a task named "debug:off" which I call at the start of my build chain:
var gulp = require('gulp');
var debug = true;
gulp.task('debug:off', function (cb) {
debug = false;
cb();
});
// ...
gulp.task('build:dev', gulp.parallel('task1', 'task2'));
gulp.task('build', gulp.serial('debug:off', 'build:dev'));
Another way is instead of using a variable like that, you could also set an environment variable when you run Gulp. Works for all versions of Gulp.
// gulpfile.js
var debug = process.env.PROD
// command-line, debug mode
$ gulp
// command-line, prod mode
$ PROD=1 && gulp
The environment variable isn't my preference, but others seem to prefer it to using a task to configure a variable.