Dependency management with RequireJS

With modern IDEs, it is possible for a developer to open a file by typing just a few characters of that file's name. This feature, along with a general desire to keep code organized, has motivated developers to separate their code into multiple files. In Backbone, this typically means creating one file for every Collection, Model, View, and Router, and even in a small project, this can add up to a lot of files.

All these files create two problems. First, each file needs to be downloaded separately, and as we learned in Chapter 8, Scaling Up: Ensuring Performance in Complex Applications, browsers can only download between 2 and 8 files at once. Second, the order in which files are loaded can become increasingly hard to manage, because of the dependencies among the different files (View A needs Collection B, which needs Model C, which needs …). RequireJS (http://requirejs.org/) solves both of these problems.

RequireJS does this by organizing your code into modules. Each module can optionally depend on one or more other modules, and RequireJS will take care of stitching the modules together in a way that preserves all of their dependencies. RequireJS also provides a related tool, called RequireJS Optimizer, which allows you to combine multiple modules into a single file. The optimizer can also "minify" your code, as well as "uglify" it, making it harder for others to understand (to prevent competitors from reading your source files).

Here's an example RequireJS module for a BookList View class:

// All RequireJS modules start by calling a special "define" function
define([
    // The module's dependencies are the first argument
    'collections/Books', // dependency on collections/Books.js
    'models/Book'       // dependency on models/Book.js

// The function that defines the module is the second argument
], function(
    // The variable names for each dependency make up the arguments to that function    Books, // alias the "collections/Books" module as "Books"
    Book   // alias the "models/Book" module as "Book"
) {
    // The actual module itself goes here
    var BookList = Backbone.View.extend({
        // Logic for our BookList View would go here; presumably it
        // would use both Book and Books
    });
    // To tell RequireJS what variable this module should "define" simply return
    // that variable at the end
    return BookList;
    // in other words, whatever is returned will be what is passed in
    // to other modules that depend on this one
});

RequireJS's style of managing dependencies is known as the AMD style. There is also a competing style, known as Common JS, which is used by other dependency management libraries such as Browserify or Hem. Common JS modules look significantly different; here's our previous example rewritten using Browserify's Common JS syntax:

// Dependencies are brought in by using the "require" function
// The module aliases are defined on the same line using the 
// standard JavaScript syntax for declaring a variable
var books = require('collections/Books'),
var book = require('models/Book'),
// Just as before, the contents of the module are defined using
// standard JavaScriptBookList = Backbone.View.extend({
    // Logic for our BookList View would go here; presumably it would
    // use both Book and Books
});
// Instead of returning what the module defines, in CommonJS modules
// are "exported" by assigning them to a "module.exports"module.exports.BookList = BookList;

The downside to this approach is that the actual ordering of the modules isn't handled for you, as it is in RequireJS. Instead, the order of the modules must be spelt out separately using require statements:

<script src="fileWithModuleDefinitions.js"/>
<script>
require('collections/Books'),
require('models/Book'),
require('views/BookList'),
</script>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.12.209