Browserify with Sourcemaps
Browserify lets you write modular JavaScript in node.js style. At the beginning of each module you write, the respective dependencies are added using require statements. Then Browserify compiles the modules along with all of the dependencies into an optimized JavaScript file for use in the browser.
If jQuery has already been loaded by a CDN or otherwise, a Browserify Shim can be used to include global jQuery as a module.
Requirements
- Node.js and the Node Package Manager (NPM) that comes with it.
- Browserify
- Gulp
- Command shell such as terminal, Git bash or Windows Command prompt.
Install Browserify
Using a Command shell, enter npm commands as follows: *
# global browserify install
npm install -g browserify
If you have an older version of global Browserify, run npm rm –global browserify to remove the old version before installing the newer one.
Create package.json
The package.json file contains project metadata and lists dependencies that are available on npm.
# create package.json
npm init
Install both jQuery and Lo-Dash from npm
# install dependencies
npm install jquery lodash --save
Updated on October 24, 2015
Local Modules
In the /src/js/modules
folder, create a local application module. In this example, the service.js local module uses jQuery ajax to get data from a rest endpoint that returns json data. Then Lo-Dash is used to output the json data in the browser with a simple template.
service.js
var $ = require('jquery');
var _ = require('lodash');
var setElementHtml = require('./element');
module.exports = function() {
var module = {
init: function() {
var tmplSource = $('#tmpl-artist').html(),
template;
$.getJSON('/api/chinook/artists').done(function(data) {
if (data) {
template = _.template(tmplSource)({
data: data
});
$(".artist-list").html(template);
setElementHtml('#some-id', 'Done');
}
});
}
};
return module.init();
};
In the /src/js/modules
folder, create a second local application module. This module depends on jQuery and contains a small function to update element HTML. Here we are simply using it to change the page heading as various steps are completed in this small application. It also shows how multiple module dependencies are defined and how they interact with each other.
element.js
var $ = require('jquery');
module.exports = function(selector, data) {
return $(selector).html(data);
};
Application Entry Point
In the /src/js
folder, create an index.js
JavaScript file.
index.js
var setElementHtml = require('./modules/element');
var getServiceData = require('./modules/service');
setElementHtml('#some-id', 'Step 2...');
getServiceData();
Build
Use the Gulp task and build runner to configure and run the build process. Install Gulp and the Node modules locally that are needed to properly minify and sourcemap the Browserify JavaScript bundle.
Install Gulp
Install gulp globally with the npm install -g
command as follows:
# global gulp install
npm install -g gulp
If you have an older version of global Gulp, run
npm rm –global gulp
to remove the old version before installing the newer one.
Install Remaining Node Modules
npm install gulp --save
npm install browserify --save
npm install vinyl-source-stream --save
npm install vinyl-buffer --save
npm install gulp-uglify --save
npm install gulp-sourcemaps --save
npm install gulp-util --save
Create a gulpfile.js
in the project root for instructing gulp to perform the tasks.
gulpfile.js
'use strict';
var browserify = require('browserify');
var browserSync = require('browser-sync').create();
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');
gulp.task('javascript', function () {
// set up the browserify instance on a task basis
var b = browserify({
entries: './src/js/index.js',
debug: true
});
return b.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
// Add transformation tasks to the pipeline here.
.pipe(uglify())
.on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./js/'));
});
// Static server
gulp.task('server', function() {
browserSync.init({
server: {
baseDir: "./"
}
});
gulp.watch('./js/*.js').on('change', browserSync.reload);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Browserify App</title>
</head>
<body>
<h1 id="some-id">Step 1 ...</h1>
<!-- template wrapper -->
<ul class="artist-list"></ul>
<!-- template -->
<script id="tmpl-artist" type="text/tmpl">
<% _.forEach(data,function(artist) { %>
<li data-artist-id="<%= artist.ArtistId %>"><%= artist.Name %></li>
<% }); %>
</script>
<script type="text/javascript" src="/js/app.js"></script>
</body>
</html>
Run
Using a Command shell, run the gulp javascript
task to Browserify the modules into a single JavaScript file, /js/app.js
, with respective source map file, /js/app.js.map
.
# run the task
gulp javascript
Server
Run the gulp server
task to load the app in the browser using a BrowseSync static server. The gulp.watch
event handler provides live reloading when the /js/app.js
file is regenerated by the gulp javascript task.
# run the task
gulp server
Source Code
UPDATE: March 26, 2016
Browserify Shim jQuery
Browserify shim to use external / global jQuery loaded from a CDN. Source code is available for browsing and download at GitHub.