Skip to content

Instantly share code, notes, and snippets.

@ForbesLindesay
Created March 26, 2013 07:51
Show Gist options
  • Save ForbesLindesay/5243763 to your computer and use it in GitHub Desktop.
Save ForbesLindesay/5243763 to your computer and use it in GitHub Desktop.

Standalone Browserify Builds

Browserify now supports standalone builds thanks to integration with my umd (universal module definition) library. Universal module definition is a simple tool to help you (as a library author) deal with the fact that all your users are probably stuck working on legacy systems with legacy build managers (such as AMD).

The goal on your part is to write your code once, in the easiest module system, and have all your users get a copy that's "optimised" for them. You want to have one file that will work in all the build systems out there. By using the umd library or the standalone option in browserify, you get just this.

Creating a Package

Consider an example package made of two files:

beep.js

var shout = require('./shout.js');
module.exports = function beep() {
  console.log(shout('beep'));
}

shout.js

module.exports = function shout(str) {
  return str.toUpperCase() + '!';
};

If you're in the browserify/CommonJS world, you can just require('./beep.js')(); and 'BEEP!' will get logged. If you're not though, you'll want a standalone build:

Using the Command Line

$ browserify beep.js --standalone beep-boop > bundle.js

Using teh API

var fs = require('fs');
var browserify = require('browserify');
var b = browserify('./beep.js');
b.bundle({standalone: 'beep-boop'}).pipe(fs.createWriteStream(__dirname + '/bundle.js'));

You've now generated the bundle and can provide it to your users.

Consuming a bundle

Depending on the environment you're in, there are a number of ways you can consume the package:

CommonJS

If you're in a CommonJS like environment that's just not quite fully browserify compatible (perhaps you're using clever transforms), you can just requiure('bundle'):

app.js

require('bundle.js')();

Logs:

BEEP!

RequireJS

If you're using RequireJS it works just as well:

index.html

<script src="require.js"></script>
<script src="app.js"></script>

app.js

require('bundle.js', function (beep) {
  beep();
});

Logs:

BEEP!

SES (Secure Ecma Script)

If you're using Secure Ecma Script you can just call ses.makeBeepBoop:

ses.makeBeepBoop()();

Logs:

BEEP!

Global/Window

If you're not using a module system at all, you can still access the package. If you're in a browser it will be at window.beepBoop and if you're in another environment it'll be at global.beepBoop. You don't need to be explicit about he window prefix though:

index.html

<script src="bundle.js"></script>
<script src="app.js"></script>

app.js

beepBoop();

Logs:

BEEP!

Bonus Feature

This UMD implementation is highly robust. It's clever enough to prevent any UMD definitions inside files you've browserified from getting confused. They won't see define, ses, bootstrap etc. so they'll just use the CommonJS option (assuming they have one).

Extending

If we don't support your chosen module system yet, I'm happy to extend things so that UMD does. Just submit a pull request for umd/template.js that adds support for your library and I'll be sure to accept it (providing it's not going to break any of the other sollutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment