Last Updated: February 25, 2016
·
4.621K
· optilude

Gulpfile for projects with LESS, Browserify and React

This gulpfile.js provides the following:

  • A js target that builds a JavaScript bundle using browserify
  • A css target that builds a single CSS file using less
  • Support for a --production flag, which will minify sources
  • A watch target that runs watchify for the JavaScript sources and standard gulp.watch() for the LESS sources for robust real-time reloading of both.

Configure it by changing the variables near the top, under the imports.

You need to install a bunch of packages:

$ npm install --save-dev browserify reactify watchify vinyl-source-stream gulp gulp-sourcemaps gulp-util vinyl-buffer gulp-less yargs gulp-if gulp-minify-css gulp-uglify

Then create gulpfile.js as per below:

/*jshint globalstrict:true, devel:true, newcap:false */
/*global require */

/**
 * Build CSS and JavaScript using `gulp`.
 *
 * Main targets are: `js`, `css` and `watch`.
 *
 * Run with `--production` to get minified sources.
 */

"use strict";

var argv = require('yargs').argv,

 gulp = require('gulp'),
 gutil = require('gulp-util'),
 gulpif = require('gulp-if'),

 source = require('vinyl-source-stream'),
 buffer = require('vinyl-buffer'),
 sourcemaps = require('gulp-sourcemaps'),
 browserify = require('browserify'),
 watchify = require('watchify'),
 reactify = require('reactify'),
 uglify = require('gulp-uglify'),

 less = require('gulp-less'),
 minifyCSS = require('gulp-minify-css');

// Directory where static files are found. Don't forget the slash at the end.
var staticDirectory = './static/',

 // Source and target JS files for Browserify
 jsMainFile = staticDirectory + 'js/app.jsx',
 jsBundleFile = 'bundle.js',

 // Source and target LESS files
 cssMainFile = staticDirectory + 'less/styles.less',
 cssFiles = staticDirectory + 'less/**/*.less';

// Browserify bundler, configured for reactify with sources having a .jsx extension
var bundler = browserify({
 entries: [jsMainFile],
 transform: [reactify],
 extensions: ['.jsx'],
 debug: !argv.production,
 cache: {}, packageCache: {}, fullPaths: true // for watchify
});

// Build JavaScript using Browserify
gulp.task('js', function() {
 return bundler
 .bundle()
 .pipe(source(jsBundleFile))
 .pipe(buffer())
 .pipe(gulpif(!argv.production, sourcemaps.init({loadMaps: true}))) // loads map from browserify file
 .pipe(gulpif(!argv.production, sourcemaps.write('./'))) // writes .map file
 .pipe(gulpif(argv.production, uglify()))
 .pipe(gulp.dest(staticDirectory));
});

// Build CSS
gulp.task('css', function(){
 return gulp.src(cssMainFile)
 .pipe(less())
 .pipe(gulpif(argv.production, minifyCSS({keepBreaks:true})))
 .pipe(gulp.dest(staticDirectory));
});

// Watch JS + CSS using watchify + gulp.watch

gulp.task('watchify', function() {
 var watcher = watchify(bundler);
 return watcher
 .on('error', gutil.log.bind(gutil, 'Browserify Error'))
 .on('update', function () {
 watcher.bundle()
 .pipe(source(jsBundleFile))
 .pipe(buffer())
 .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
 .pipe(sourcemaps.write('./')) // writes .map file
 .pipe(gulp.dest(staticDirectory));

 gutil.log("Updated JavaScript sources");
 })
 .bundle() // Create the initial bundle when starting the task
 .pipe(source(jsBundleFile))
 .pipe(gulp.dest(staticDirectory));
});

gulp.task('csswatch', function () {
 gulp.watch(cssFiles, ['css']);
});

gulp.task('watch', ['watchify', 'csswatch']);
gulp.task('default', ['js', 'css']);