The CommonJS Module Loader






Presenter: Stanislav Venzerul

What is it?


As JS projects grew in size and complexity, front-end developers recognized the need to organize and modularize their code.  Unlike most programming languages, however, JS does not come with a baked in module system. 

Something had to be done. Solutions like RequireJS and Browserify quickly cropped up to fill the gap. We will now examine the differences, pros and cons of Browserify versus the AMD module systems.

Browserify And Commonjs


As some of you may know, the module system used by Node.js named CommonJS is a rather simple and clean way of introducing modules intro Javascript. 

How nice would it be if you could just "require('moduleA')" and the modules' exported value would be returned to you ready to be used?

 var base64 = require('base64');

Although Browserify was originally designed specifically to make NPM modules available in the browser, it has proven itself useful as a general module loader. 

The basics


First let's look at how to create a simple CommonJS module.


 var Base64 = {   encode: function(data) {},   decode: function(data) {} } module.exports = Base64;
 

Behind the scenes Browserify wraps your module in a closure. Every module has a 'module.exports' object available to it by default. Anything you assign to this object will become available outside of the module. Everything else is private.

require it


Here's a simple example of using Browserify to load a fictitious Base64 encoder/decoder module. 


 var base64 = require('base64'); var str = 'some string'; console.log('Encoded: ' + base64.encode(str));

Once the module is require'd in, whatever object/s the module chooses to export will become available as the return value of the require call. Sweet and simple.

Bundle it

So you've got your project all nice and modularized, you're feeling good, but then you realize now you have to load this whole thing into the browser and make sure the order is correct. 

Fear not! Browserify will bundle up and optimize the whole thing for you, starting from a chosen entry point which you can conveniently call main.js.

$ browserify main.js -o bundle.js

The command above will take your entry point, walk the entire dependency graph, and generate a single file package into bundle.js. Now just <script src="bundle.js"> in the browser and you're done. 

An IMPortant question

Is Browserify Asynchronous?

An important answer

No.

A bit more detail: Since browserify bundles up your files into a single file there's nothing to load asynchronously. This minimizes HTTP requests and is easy to minify as well if needed. 

But what about development time?, I hear you think. I'm glad you asked. At the moment the best solution is to use source-maps which can be enabled with the --debug build flag.


loading node.js modules

As mentioned in the beginning, Browserify was originally designed to allow the loading of NPM modules in the browser for some awesome code resuse purposes. 

Browserify not only allows this but also provides certain Node functions and constants like process.nextTick(), __dirname and __filename. 


A whole bunch of core node modules are available as well: events, stream, path, url, assert, buffer, util, querystring, http, vm and crypto are some good examples. 

Note: even though most things work, trying to load things like 'fs' will only result in tears.

How to Sourcemap

During development the last thing you want to be looking at is minified code. Here too browserify comes to the rescue with the --debug flag.

$ browserify --debug main.js -o bundle.js

 The above command will compile your source with sourcemaps which is a really handy way of letting the browser 'unminify' the code. bundle.js will simply have a line

that says:

//@sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyI...

This will make everything right with the world.

plugins and shtuff


So what about jQuery and plugins and friends?

Solution: https://github.com/thlorenz/browserify-shim

The shim library will fix up any version of a library so you can just do: 

 var $ = require('jquery');
Even better, as of jQuery 2.0.0 supported has been added for CommonJS and AMD, so just go ahead and use that.

What about jquery-browserify? Don't! you'll be stuck with that version of jQuery and tears will be had when time comes to upgrade.

questions?


go forth and browserify!

deck

By signupskm

deck

  • 1,566