React + Backbone + RequireJS

Last time we looked at how to use React to render views in combination with the Backbone router. Today we’ll see how to build the latest React version and load both React and Backbone using RequireJS.

RequireJS is a file/module loader library which is optimised for browser use. It’s often used in the structuring of large JavaScript codebases, to load modules on demand (asynchronously).

Please post any errors you find, or questions you have as comments on this article. Thanks to Wayne Berry, Ricardo Mendes and Thomas Coopman for helping to improve this!

Building Edge React

The version you first see, on the React homepage (http://facebook.github.io/react/index.html) is not always the most up-to date version you could use. To get the latest version, we need to follow a few steps:

Clone the React GitHub repo. Install the required NPM modules. Build the distribution files. To clone the React GitHub repo, use the following command:

git clone https://github.com/facebook/react.git

Next, navigate to the new clone directory and install the required NPM modules:

npm install

Finally, build the distribution files, using Grunt:

grunt

The first step assumes you have Git command-line utility installed (http://git-scm.com). The second, that you have NPM command-line utility installed (https://npmjs.org). The third, that you have Grunt command-line utility installed (http://gruntjs.com). I won’t walk you through installing them.

After Grunt has finished compiling the React source-code, you will see a build folder, filled with compiled JavaScript files. The ones you are probably looking for are react[-with-addons].js and JSXTransformer.js. There are also NPM-friendly modules, if you’re looking to run React in Node.

It’s not always the best idea to use an edge version of React. The version I just compiled is clearly marked as an alpha version, and these are not always production ready.

Using RequireJS

RequireJS is just another JavaScript library. Download the source at: http://requirejs.org/docs/download.html. You’ll then need to include it in your HTML page:

<script data-main="main.js" src="require.js"></script>

If you’re structuring your JavaScript codebase the usual way, this will be the only script file you need to include directly. Everything else should be loaded asynchronously, and the origin of this loading will be the contents of main.js.

Every application needs an entry-point. The first bit of JavaScript to load all other JavaScript. That happens in main.js. You can call it whatever you like, but you should include it in the data-main attribute or RequireJS won’t know how to bootstrap your application code.

You can learn more about RequireJS at: http://requirejs.org.

Holding Backbone’s Hand

RequireJS support is virtually non-existent in Backbone. I’m not sure why this should be, as it’s trivial to support RequireJS without sweeping changes to Backbone’s codebase, but there you have it.

As previously seen, Backbone requires jQuery (http://jquery.com/ download) and Underscore (http://underscorejs.org), so go ahead and download these. Don’t link them yet, as we will do this in main.js.

These libraries typically register themselves in the global namespace. That’s on the opposite end of the spectrum to RequireJS. Unfortunately, Backbone doesn’t care, so we need to continue to include them in the global namespace for Backbone to work.

This is done, in RequireJS, with what’s called a shim configuration. My main.js file looks like this:

require.config({
  "baseUrl" : "/js",
  "paths"   : {
    "jquery"     : "path/to/jquery",
    "underscore" : "paht/to/underscore",
    "backbone"   : "path/to/backbone",
    "react"      : "path/to/react"
  },
  "shim" : {
    "backbone" : {
      "deps" : [
        "jquery",
        "underscore"
      ],
      "exports" : "Backbone"
    },
    "jquery" : {
      "exports" : "$"
    },
    "underscore" : {
      "exports" : "_"
    }
  }
});
 
require(["backbone", "router"], function(Backbone, Router) {
  new Router();
  Backbone.history.start();
});

My router.js file looks like this:

define(["backbone"], function(Backbone) {
  return Backbone.Router.extend({
    routes : {
      "" : "index"
    },
    index : function() {
      console.log("hello world");
    }
  });
});

We’re doing a number of important things in the RequireJS configuration:

set the JavaScript root directory so RequireJS knows where to begin looking for module files. We define a number of module aliases. These are shortcut alternatives to defining the entire file path when needing to include a module like jquery. We create the shim configuration for Backbone, specifying dependencies, and what each of them export for Backbone’s use. I mentioned that the bootstrapping (entry-point) of the application code happens in main.js. That’s what the bottom bit is about — we require the router, instantiate it and start Backbone’s history. We could do this in an external module file, or whatever. It’s not important.

sources

[react-tutorials] : https://medium.com/react-tutorials/react-edge-backbone-requirejs-15602e6f88fa