Solarian Programmer

My programming ramblings

Modular JavaScript development with Browserify and LivePage

Posted on February 5, 2014 by Sol

Working on a medium to large scale JavaScript project was always a challenge. Just picture yourself editing a few thousands lines of code in a single source file! Fortunately, the next version of the JavaScript standard, ECMAscript 6, is going to give us modules. Personally, I think that the golden standard for JavaScript modules is the Node.js model, what could be more elegant than to write:

1 require('foo');

and instantly have access to everything was exported in the required module ?

In the past, a possible solution to the above problem was to use an AJAX call to load a piece of JavaScript code in another file, e.g. jQuery.getScript(). More recently, like a few years ago, RequireJS become the state of the art approach. With RequireJS you would write:

1 require(["foo"], function(foo) {
2 	//This is called when foo.js is loaded.
3 }

this gives us a callback function that will fire once the required module is loaded. But, what if you want something even simpler, something that looks more like the Node.js syntax, or Lua’s require, or other languages ? Enter Browserify!

With Browserify you can use a simple syntax and avoid the use of an extra callback function. Basically, Browserify works like a compiler, you specify a list of input JavaScript files and they will be combined in a single file, something like:

1 browserify input_1.js input_2.js -o bundle.js

Obviously, it will be rather tedious to use the above command each time you change something in one of your JavaScript input files. We could use watchify to watch for changes and run browserify for us. Watchify uses the same syntax as browserify:

1 watchify input_1.js input_2.js -o bundle.js

Now, every change in one of the input JavaScript files will trigger a rebuild of the output, bundle.js file.

You can install browserify and watchify with the NodeJS manager npm. Assuming you have installed NodeJS on your computer, open a Terminal (for Windows you could use a Command Prompt, just remove the sudo from both lines) and write:

1 sudo npm install -g browserify
2 sudo npm install -g watchify

Now, we are ready to use require in our JavaScript files. Let’s start with a simple example:

 1 function Person(first_name, last_name, age) {
 2 	this.first_name = first_name;
 3 	this.last_name = last_name;
 4 	this.age = age; 
 5 }
 7 Person.prototype.getName = function() {
 8 	return this.first_name + " " + this.last_name;
 9 }
11 Person.prototype.getAge = function() {
12 	return this.age;
13 }
15 module.exports = Person;

Please note the highlighted line from above, this will let us use the object Person in a different file. Save the above file as person.js.

Now, we could use the above code in a separate JavaScript file:

 1 (function() {
 2 	var Person = require('./person.js');
 4 	// create and use two persons
 5 	var person_1 = new Person("William", "Adama", 65);
 6 	var person_2 = new Person("Lee", "Adama", 30);
 8 	console.log(person_1.getName());
 9 	console.log(person_2.getName());	
10 })();

save the above as main.js. We can compile the above two files using browserify through watchify:

1 watchify person.js main.js -o bundle.js

Let’s include bundle.js in a dummy html file:

 1 <!DCCTYPE html>
 2 <html>
 3 	<head>
 4 		<title>Using Browserify</title>
 5 	</head>
 7 	<body>
 8 		<script src = "bundle.js"></script>
 9 	</body>
10 </html>

save the above as test.html and open it in a browser. If you open the JavaScript console from your browser developer tools you should see something like this:

figure 1

Now, add an extra line to main.js and save the file:

 1 (function() {
 2 	var Person = require('./person.js');
 4 	// create and use two persons
 5 	var person_1 = new Person("William", "Adama", 65);
 6 	var person_2 = new Person("Lee", "Adama", 30);
 8 	console.log(person_1.getName());
 9 	console.log(person_1.getAge());
10 	console.log(person_2.getName());	
11 })();

the output file, bundle.js, will be generated for you, if you refresh the test.html in your browser, you should see:

figure 2

What if you want to automatically refresh your webpage when one of the input JavaScript is changed ? If you use Google Chrome there is an extension for that, LivePage. Enable LivePage and each time you will change one of your JavaScript files the page will be reloaded. For e.g. add an extra line at the end of main.js:

1 (function() {
2 	...
3 	console.log(person_2.getName());	
4 	console.log(person_2.getAge());
5 })();

and the result, assuming LivePage was enabled:

figure 3

If you want to be able to read bundle.js or to see where an error has occurred in the original JavaScript files, use the –debug flag:

1 watchify --debug person.js main.js -o bundle.js

The above will enable source maps for your input files.

If you want to learn more about JavaScript, I would recommend reading Secrets of the JavaScript Ninja by J. Resig and B. Bibeault:

If you are interested in Node.js, this is a good book Node.js the Right Way by J. R. Wilson:

comments powered by Disqus