In my last blog post I explained how to use browserify command line to bundle javascript modules. In this we will use browserify api to use it along with gulp. I will be writing gulpfile snippets for this post in ES6. You can checkout my post on writing gulpfile in ES6.
import gulp from "gulp";
import browserify from "browserify";
import fs from "fs";
gulp.task('default', () => {
browserify({
entries: 'src/utils.js',
debug: true
})
.bundle()
.pipe(fs.createWriteStream('./dist/utils.js'));
});
A basic implementation can be done as above. But this won’t work when you need to pipe with other gulp plugins like uglify
or gulp.dist
. This is because browserify.bundle()
return a text stream where as gulp works using vinyl stream. In order to browserify to work with other plugins you need to use vinyl-source-stream.
vinyl-source-stream
will convert text streams from browserify.bundle()
to vinyl streams so you can pipe with other gulp plugins which support streaming. Install the vinyl-source-stream
using npm i --save-dev vinyl-source-stream
.
import gulp from "gulp";
import browserify from "browserify";
import source from "vinyl-source-stream";
gulp.task('default', () => {
browserify({
entries: 'src/utils.js',
debug: true
})
.bundle()
.pipe(source('utils.js'))
.pipe(gulp.dest('./dist'));
});
Now we can use gulp.dest
to write the output file but if we try to pipe it to gulp-uglify
you will get error saying Streaming not supported. This is because some gulp plugins doesn’t support streaming. The vinyl-source-stream
returns a streaming vinyl object where as uglify expects buffered vinyl file objects.
Thats were vinyl-buffer
comes in. vinyl-buffer
will convert streaming vinyl files to use buffer. you install vinyl-buffer using npm i --save-dev vinyl-buffer
import gulp from "gulp";
import browserify from "browserify";
import uglify from "gulp-uglify";
import source from "vinyl-source-stream";
import buffer from "vinyl-buffer";
gulp.task('default', () => {
browserify({
entries: 'src/utils.js',
debug: true
})
.bundle()
.pipe(source('utils.min.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('./dist'));
});
Now in dist/utils.min.js
you will get minified version of the build.
Working with Source Maps
If you want to generate sourcemaps for your builds you can use gulp-sourcemaps
plugin. Install gulp-sourcemaps using npm i --save-dev gulp-sourcemaps
.
import gulp from "gulp";
import browserify from "browserify";
import uglify from "gulp-uglify";
import source from "vinyl-source-stream";
import buffer from "vinyl-buffer";
import sourcemaps from 'gulp-sourcemaps';
gulp.task('default', () => {
browserify({
entries: 'src/utils.js',
debug: true
})
.bundle()
.pipe(source('utils.min.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist'));
});
Handling Errors
In order to handle errors you bind callback to ‘error’ event from browserify.
import gulp from "gulp";
import browserify from "browserify";
import uglify from "gulp-uglify";
import source from "vinyl-source-stream";
import buffer from "vinyl-buffer";
import sourcemaps from 'gulp-sourcemaps';
import 'gutil' from 'gulp-util';
gulp.task('default', () => {
browserify({
entries: 'src/utils.js',
debug: true
})
.bundle()
.on('error', err => {
gutil.log("Browserify Error", gutil.colors.red(err.message))
})
.pipe(source('utils.min.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist'));
});
Using with react and babel
If you are planning to right react components in ES6 then I recommend babelify
transform, otherwise reactify
transform will help to bundle the react modules.
import gulp from "gulp";
import browserify from "browserify";
import uglify from "gulp-uglify";
import source from "vinyl-source-stream";
import buffer from "vinyl-buffer";
import sourcemaps from 'gulp-sourcemaps';
import 'gutil' from 'gulp-util';
import babelify from 'babelify';
gulp.task('jsx', () => {
browserify({
entries: 'src/index.jsx',
extensions: ['.jsx'],
debug: true
})
.transform(babelify)
.bundle()
.on('error', err => {
util.log("Browserify Error", util.colors.red(err.message))
})
.pipe(source('index.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist'));
});
Image courtesy keyholesoftware.com