wisew
wisew

Reputation: 2882

Is it possible to assign a variable in a gulp task before running dependencies?

I'm trying to conditionally pipe a file stream based on the value of a variable, as a way to define two separate build environments (ie. development and production).

Some tasks can be run individually with a command-line flag like so: gulp scripts --env production

And will then do some production-only pipeline steps:

gulp.task('scripts', function() {
  var jsFilter = filter(['*.js']),
  appFiles;

  return gulp.src(appFiles)
    .pipe(jsFilter)
    .pipe(concat('application-build.js'))
    .pipe(gulpif(env === 'production', uglify()))
    .pipe(size())
    .pipe(gulpif(env === 'production', gulp.dest('dist/js'), gulp.dest('tmp/js')))
    .pipe(browserSync.reload({ stream: true }));
});

I have a build task that calls a number of other tasks as dependencies (including this scripts task for instance). I want this build task to assign a variable (env, in this case) before running task dependencies. Which means that this:

gulp.task('build', ['scripts', 'styles', 'otherstuff'], function() {
  env = 'production';
}

doesn't work, because the dependencies are run before the body of the task.

I currently have it implemented with gulp.start:

gulp.task('build', function() {
  env = 'production';
  gulp.start('scripts');
});

But the .start method isn't actually part of gulp's public API - it comes from Orchestrator - and isn't intended to be used for anything. Plus, the equivalent method gulp.run was deprecated from the API awhile ago.

So I'm wondering - is there another way I could assign a variable in a task before running its dependencies?

(Or maybe there's a better way to to implement something like build environments in gulp?)

Upvotes: 20

Views: 17273

Answers (2)

Evan Carroll
Evan Carroll

Reputation: 1

THE RIGHT WAY

I disagree with @Justin. Defining an environmental variable with a task is a hackjob of an idea. This is better done with gutil.env this way.

gulp --env prod task

gulp.task( 'myTask', () => { console.log( gutil.env.env ) } )

Now from this point, you have gulp.env.env set.

Or, alternatively you can do like this example in this ticket.. which addresses this from the developers of Gulp which first suggest to use an environmental variable, but provide this idiom..

function js(shouldMinify) {
    return gulp.src('./js/*.js')
        .pipe(concat('app.js'))
        .pipe(gulpif(shouldMinify, uglify()))
        .pipe(gulp.dest('js'));
});

gulp.task('develop', function () {
    shouldMinify = false;
    return js(shouldMinify);
});

gulp.task('build', function () {
    shouldMinify = true;
    return js(shouldMinify);
});

That same developer (phated) always says to use env...

Not to mention, you should control this type of logic with environment variables or command line flags. - phated

Presumably, he's referring to the use of gutil.noop() in gulp-util's docs:

// gulp should be called like this :
// $ gulp --type production
gulp.task('scripts', function() {
  gulp.src('src/**/*.js')
    .pipe(concat('script.js'))
    // LOOK BELOW: if we don't send to uglify, we push to noop stream.
    .pipe(gutil.env.type === 'production' ? uglify() : gutil.noop())
    .pipe(gulp.dest('dist/'));
});

Upvotes: 21

Justin Howard
Justin Howard

Reputation: 5643

You could create a task specifically to set the environment and run it before your other tasks.

gulp.task('set-production', function() {
  env = 'production';
});

// Doesn't quite work because tasks are run in parallel
gulp.task('build', ['set-production', 'scripts', 'styles', 'otherstuff']);

The problem here is that your tasks will be run in parallel, meaning the set-production task may be run after the other tasks. You can solve this problem with the run-sequence package.

var runSequence = require('run-sequence');
gulp.task('build', function(callback) {
  runSequence('set-production', ['scripts', 'styles', 'otherstuff'], callback);
});

This will run the set-production task first, then run the scripts, styles, and otherstuff tasks in parallel.

Upvotes: 13

Related Questions