I am working on a javascript app with backbone.js, that said, for ease of development I structure my files this way
app
|
+ views
| L movieRow.js
| L movieDetail.js
|
+ models
| L movie.js
| L tvshow.js
|
+ collections
| L movies.js
| L tvshows.js
|
+ templates
| L movieList.tpl
| L movieDetail.tpl
| L applicationUI.tpl
|
L application.js
now, that are a lot of javascript files to server to the user, I see some buzz about labjs or require.js and decided to test around with it. but i have no idea how i would rewrite all my backbone models or views into these require.js modules.
any help in the right direction would be nice.
The key to understanding require (at least in my small brain) is to remember that what you return from the function will be available to other modules that pull in (or require) this module. So in the code below, I need jquery and backbone (jquery is a special case handled by "require-jquery"). When those 2 are available it will call my function and that function will return the View constructor that I created.
define([
'jquery'
'libraries/backbone'
], function ($) {
var MovieRow = Backbone.View.extend({
render: function () {
return this;
}
});
return MovieRow;
});
Then you might write something like this to your page. Note that jquery is the first required item in the array. This corresponds to the first parameter in my function. The View is 2nd and the Model is 3rd. Then I can use the return value from my "define" code above which is the constructor.
require({
baseUrl: '/'
},[
'jquery',
'app/views/movieRow',
'app/models/movie',
'libraries/backbone'
],
function ($, MovieRowView, Movie) {
var view = new MovieRowView({model : new Movie());
$('body').append(view.render().el);
});
Hope this is helpful... We've been loving Backbone and Require :)
I ran out of space in comments and wanted to include some code so I am producing a second answer:
What @timDunham posted is for the most part pretty good although I have a few extras that someone might chime in on for further understanding.
In the code:
define([
'jquery'
'libraries/backbone'
]
I believe Underscore is missing. First, Backbone needs Underscore in order to operate and without it I think it would break. Second, unless you're using the AMDJS fork of Underscore and Backbone, they aren't AMD supportive. Underscore REMOVED AMD support with v1.3.0. If we assume we're using non-AMD underscore and backbone, they probably don't belong in the define[]
and should be require[]
instead.
So the proper define would look something like this IF you're properly using the AMDJS versions:
define([
'jquery',
'underscore',
'Backbone'
], function($, _, Backbone) { ... });
This assumes I created the paths in the require config:
require.config({
paths : {
jquery : 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min',
underscore : '../../libs/js/underscore/underscore.min',
Backbone : '../../libs/js/backbone/backbone',
}
});
I've seen some implementations that don't use the AMDJS versions and the thing with those is that since they aren't asynchronous modules, you have to make sure they are loaded in the correct order.
I believe this does NOT guarantee the correct order of loading dependencies:
require({
baseUrl: '/'
},[
'jquery',
'app/views/movieRow',
'app/models/movie',
'libraries/backbone'
],
Because something is listed as a dependency, doesn't mean it will load when needed. With asynchronous modules it isn't a problem but in this example I didn't see it mentioned so we'll assume they aren't AMD. This module DEPENDS on jquery, movieRow, movie, and backbone. But if backbone tries to load before jquery... (x_x) Why world why?
Which is why I believe require.js has a plugin called order! to the rescue. With order! you can set up your dependencies and it loads the scripts in ... well... order. Something like this:
require({
baseUrl: '/'
},[
'order!jquery',
'app/views/movieRow',
'app/models/movie',
'order!libraries/underscore', // <- Don't forget me!
'order!libraries/backbone'
]
I believe with this, your module will evaluate and guarantee that jquery is loaded first, then underscore, then backbone. No guarantees for movieRow or movie although in this case, who cares? :-)
I use the AMDJS-Backbone and AMDJS-Underscore forks for my project so I usually put them in the define[]
and it works without a hitch. RequireJS really is awesome and has cleaned up my code significantly. Everywhere I go JRBurke the writer of RequireJS pops up everywhere and he's always super duper helpful with his comments on everything concerning require.js. And I mean everything. My theory is that he is telepathically connected to Require and any time a new instance of requirejs occurs on the web, he has immediate access to that knowledge. I bet that if this thread discussion continues he'd pop up here to say hello also.
My disclaimer is that I'm also new to Require and I might be misunderstanding things. But from what I know, I thought these extra pointers and info might help people put together better code using require.
REFERENCES:
- https://github.com/amdjs/underscore
- https://github.com/amdjs/backbone
- http://requirejs.org/docs/api.html#order