Very basic Backbone/Underscore via Require.js issue driving me batty

12,032

Solution 1

I have actually spent a lot of time struggling with this same exact problem!

Here's how I have managed to get it working...

First off, download the new sample require-js project with jQuery 1.7. In the zip file you'll find a file called require-jquery.js which includes jQuery 1.7 which is now AMD compliant.

Then download the latest version of require, which is now also AMD, and last, try this version of Backbone...

https://github.com/jrburke/backbone/blob/optamd/backbone.js

Burke has created this off of a fork of backbone and made an AMD compliant version.

Then...
Index.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Google Analytics API Browser</title>
        <!-- This is a special version of jQuery with RequireJS built-in -->
        <script data-main="main" src="require-jquery.js"></script>
    </head>
    <body>

    </body>
</html>

main.js

require(['jquery','order!libs/underscore-min','order!libs/backbone','order!scripts/app'], 
function($,_,Backbone,app){
    app.init();
});

app.js

define(['jquery','backbone','scripts/home'], function($, Backbone, router){
    var init = function(){
        console.log("Started");
            // In here you can load your routers/views/whatever
    };

    return { init: init};
});

My file structure looks like
/app/index.htm
/app/require-jquery.js
/app/order.js
/app/main.js
/app/text.js
/app/scripts/app.js
/app/scripts/home.js
/app/lib/underscore-min.js
/app/lib/backbone.js

Let me know if that helps, hit me up on twitter @jcreamer898 if you need some more help, I am literally working on the same stuff!

UPDATE I recently created a Github 2 github projects, one an actual app, and another just a simple starter...

https://github.com/jcreamer898/Savefavs
https://github.com/jcreamer898/RequireJS-Backbone-Starter

Solution 2

Feel free to have a look on the Modular Backbone.js Project Template which contains newest jQuery, Underscore, Backbone.js and RequireJS glued together .

Solution 3

I had the same problem. Actually I found that you do not need an AMD compliant Backbone or Underscore, or require-jquery or anything else (e.g. !order). All you need to do to is have app defined in paths and than set its dependencies in shim :). Somehow it used to work without it in the past.

paths: {
    app:'app',
    jquery: '../libs/jquery/jquery.1.9.1.min',
    underscore: '../libs/underscore/underscore.min',
    backbone: '../libs/backbone/backbone.min', 
    // ...
},
shim: {
 "app": {
      deps: ['jquery','underscore','backbone'],
      exports: 'app'  
},
"backbone": {
  deps: ['jquery','underscore'],
  exports: 'Backbone'  
},
"underscore": {
  exports: '_'
}
//...

}

Solution 4

Here is an example of how to setup Backbone, lodash (Underscore replacement), jQuery, and Require: https://github.com/gfranko/Backbone-Require-Boilerplate

Share:
12,032
greenanvil
Author by

greenanvil

Updated on June 06, 2022

Comments

  • greenanvil
    greenanvil almost 2 years

    I am attempting to implement an EXTREMELY basic test that uses jquery, underscore.js and backbone.js loaded via require.js and for some reason I just cannot seem to get everything lined up properly. Research shows that others have not had these same problems so I know it must be something simple that I am just not seeing.

    The problem I am having is that when backbone.js is loading, it cannot find a reference to _. I've found other people reporting the same issue but the problem was usually passing dependency references into handlers in the wrong order or other obvious problems. This is happening when backbone is loading.

    I have also seen a number of 'mechanical' solutions such as 'put everything in the same file' and just loading them in a traditional way by having a number of script includes in the proper order but I REALLY want to get this working since it seems like such a powerful approach.

    Initially I started with the structure here http://backbonetutorials.com/organizing-backbone-using-modules/ which works in the demo, but feels a little fragile because when I attempt to make very simple modifications or build up a simple sample from the ground up, it breaks.

    After hitting my head against this for far too long, I went back and found this page Loading Backbone and Underscore using RequireJS with another simple example and I regained hope. However, after building up a new test based on it, I am STILL receiving the same issue even though the 0.5.3-optamd branch of backbone is supposed to handle its own dependency on underscore.

    Without further ado, here is the super-straight-forward code that should work but instead is driving me insane. Here's hoping it's something obvious I just missed somehow:

    index.html

    <!DOCTYPE html>
    <html>
        <head>
            <title>Backbone.js/Underscore.js via Require.js Learning Page</title>
            <script src="js/libs/require/require.js"></script>
            <script src="js/main.js"></script>
        </head>
        <body>
            <div>Backbone.js/Underscore.js via Require.js Learning Page</div>
            <div class="testhook"></div>
        </body>
    </html>
    

    js/main.js

    require.config({
        paths: { 
                'jquery': 'libs/jquery/1.7/jquery',
                'underscore': 'libs/underscore/1.2.2/underscore',
                'backbone': 'libs/backbone/0.5.3-optamd/backbone'
        },
        baseUrl: '/js',
        urlArgs: 'v=1.0'
    });
    
    require([
             'domReady',
             'app'
             ], 
             function( domReady, App ){
                domReady(function(){
                    console.log( 'Dom is ready' );
                    App.init();
                });
            }
    );
    

    js/app.js

    // Filename: app.js
    define([
            'jquery', 
            'underscore', 
            'backbone'
            ], 
            function( $, _, Backbone ){
    
                var init = function(){
    
                    console.log( 'app.js > init()' );
    
                    // jquery test (WORKS)
                    $('.testhook').append('testhook append');
    
                    // underscore test (WORKS)
                    console.log( _.map([1, 2, 3], function(n){ return n * 2; }));
    
                    // backbone test (DIES)
                    var artist = new Backbone.Model({
                          firstName: "Wassily",
                          lastName: "Kandinsky"
                        });
    
                        artist.set({birthday: "December 16, 1866"});
    
                        console.log(JSON.stringify(artist));
                }
    
                return { init: init };
            }
    );
    

    The exact console output is:

    Uncaught TypeError: Cannot call method 'extend' of undefined (backbone.js:150)
    main.js:18    Dom is ready
    app.js:11     app.js > init()
    app.js:17     [2, 4, 6]
    app.js:20     Uncaught TypeError: Cannot read property 'Model' of null (app.js:20)
    
    NOTE:
    Line 150 in unminified backbone.js is:
    _.extend(Backbone.Model.prototype, Backbone.Events, {
    

    I am on a Windows 7 machine using Chrome 17.0.938.0 dev-m.

    My script versions are:

    backbone:       0.5.3-optand
    jquery:         1.7
    require:        1.0.1
    underscore:     1.2.2
    

    My directory structure is:

    js
    +-- libs/
    ¦       +-- backbone/
    ¦       ¦     +-- 0.5.3-optamd/
    ¦       ¦                 +-- backbone.js
    ¦       +-- jquery/
    ¦       ¦     +-- 1.7/
    ¦       ¦          +-- jquery.js
    ¦       +-- require/
    ¦       ¦      +-- require.js
    ¦       +-- underscore/
    ¦              +-- 1.2.2/
    ¦                    +-- underscore.js
    +-- app.js
    +-- domReady.js
    +-- main.js
    +-- order.js
    index.html
    

    I cannot believe how much difficulty this is giving me and am really hoping someone can shed some light on what the heck is going on here.

    • Riebel
      Riebel over 12 years
      your example works for me 100%. what exact Backbone version are you using? optamd or optamd3?
  • greenanvil
    greenanvil over 12 years
    Excellent! I'll give this a shot!
  • greenanvil
    greenanvil over 12 years
    Thanks again for the information! Looks like one critical thing I was missing was making sure to call the order plugin on the main app itself to make sure it loaded (and called backbone/underscore/etc) -after- they were loaded. I intend to also look into the priority config argument as it may mitigate the need to use order. Thanks again, really. I'm not used to running into things that give me that much trouble and wanted to avoid digging into the underlying mechanics to see what was really happening (for now). I can now save that for later and get back to the fun stuff! :) Cheers!
  • greenanvil
    greenanvil over 12 years
    Was already using optamd branch (see original question). The issue appeared to be a pathing issue and perhaps a main app order issue. Once I put the main libs next to each other, stopped trying to use the path config options and sent the main app through the order plugin everything started working as expected. Thanks tho.