Search code examples
javascriptnode.jsbackbone.jsbrowserify

Complex backbone app with multiple build configurations using Browserify


I'm working on a large Backbone app that is designed to be very configurable due to being multi-tenancy and designed to run on many platforms. Currently the apps are built via Grunt and environment variables are used to determine which Backbone files are included in the finished version of the app.

At present some of the files that get included are extending or overwriting others that are included earlier.

As an example:

BaseHeader.js:

var BaseHeader = Backbone.View.extend({
    // code
});

Header.js:

var Header = BaseHeader.extend({
    // code
});

At the moment my finished app is built with Grunt which creates an .html file with a bunch of script tags so all the files will be loaded by the browser.

I'd like to use Browserify to bundle my JS into a single file, so now I have:

BaseHeader.js:

var Backbone = require("backbone");

var BaseHeader = Backbone.View.extend({
    // code
});

module.exports = BaseHeader;

Header.js:

var Backbone = require("backbone");
var BaseHeader = require("/path/to/BaseHeader.js");

var Header = BaseHeader.extend({
    // code
});

module.exports = Header;

But I'm confused as to how to work things.

The entry point for all my apps is the same App.js file which makes a require call to BaseHeader.js, it doesn't however make a require call to Header.js as this file is platform/client specific.

As Browserify simply recurses through the requires in order to find and bundle dependencies it will never pick up Header.js So, how can I create a build task to optionally require Header.js when needed?


Solution

  • Your looking for the require option to browserify:

    This option will include the module or file as part of the bundle even if it isn't referenced in the entry app. It should also expose the said module to your HTML page via a global require() function.

    From the docs:

    b.require(file, opts)

    Make file available from outside the bundle with require(file).

    The file param is anything that can be resolved by require.resolve().

    file can also be a stream, but you should also use opts.basedir so that relative requires will be resolvable.

    If file is an array, each item in file will be required. In file array form, you can use a string or object for each item. Object items should have a file property and the rest of the parameters will be used for the opts.

    Use the expose property of opts to specify a custom dependency name. require('./vendor/angular/angular.js', {expose: 'angular'}) enables require('angular')