Explain Codes LogoExplain Codes Logo

Is it possible to pass a flag to Gulp to have it run tasks in different ways?

javascript
gulp
yargs
command-line-arguments
Nikita BarsukovbyNikita Barsukov·Oct 3, 2024
TLDR

Yes, utilize Gulp with yargs to pass flags. Running gulp task --flag prompts conditional logic in your tasks. An example of a styles task:

const gulp = require('gulp'); const argv = require('yargs').argv; const minifyCSS = require('gulp-clean-css'); const sourcemaps = require('gulp-sourcemaps'); // Don't try this at home gulp.task('styles', () => gulp.src('src/css/*.css') .pipe(argv.production ? minifyCSS() : sourcemaps.init()) // CSS party trick .pipe(sourcemaps.write('.')) // Always write sourcemaps, just in case .pipe(gulp.dest('dist/css')) );

Issue gulp styles --production to compress your CSS. Alternatively, only gulp styles if you wish to include sourcemaps.

Flexing with enhanced tasks

We can place yargs into overdrive for parsing command line arguments and brace it with gulp-if to enhance your workflow. Here's how to pair them like wine and cheese:

const gulpif = require('gulp-if'); // This is where the magic happens gulp.task('scripts', () => gulp.src('src/js/*.js') .pipe(gulpif(argv.uglify, uglify())) // For those minification moments .pipe(gulp.dest('dist/js')) );

Giving gulp scripts --uglify a whirl will minify your JavaScript files. If you run it barebones with gulp scripts, the files remain unaltered.

Trigger actions based on conditions

Optimize your gulpfile by centrally managing your condition checks from a utility function:

function isProduction() { return argv.production === true; // Is it true? Is it really? } gulp.task('images', () => gulp.src('src/images/*') .pipe(gulpif(isProduction(), imagemin())) // Only hit the gym if it's showtime .pipe(gulp.dest('dist/images')) );

Using gulp images --production results in optimized images only when required.

Creating environment-specific tasks

Occasionally, tasks tend to be environment-specific. Utilize Node's process.env as an alternative:

gulp.task('deploy', () => { if (process.env.NODE_ENV === 'production') { // Deployment logic for primetime } else { // Rehearsal for other environments } });

Command NODE_ENV=production gulp deploy sets the environmental variable leading the task.

Taking charge of minification and sourcemaps

Safeguard minification in the production environment:

const uglify = require('gulp-uglify'); gulp.task('compress', () => gulp.src('scripts/*.js') .pipe(gulpif(argv.production, uglify())) // Get in shape for production .pipe(gulp.dest('scripts')) );

Stay in control of sourcemaps:

gulp.task('js', () => gulp.src('src/js/**/*.js') .pipe(gulpif(!argv.production, sourcemaps.init())) // Ain't nobody need maps in production .pipe(babel()) .pipe(gulpif(!argv.production, sourcemaps.write('.'))) // Better safe than sorry .pipe(gulp.dest('dist/js')) );

Command gulp js --production forgoes sourcemaps for nimble builds.

Manipulating file names dynamically

Adjust output filenames or paths using flags, great for versioning:

const rename = require('gulp-rename'); gulp.task('rename', () => gulp.src('*.css') .pipe(gulpif(argv.suffix, rename({suffix: '.min'}))) // Let's make this even cooler .pipe(gulp.dest('dist')) );

Take gulp rename --suffix for a spin to append .min to output filenames.